code init

This commit is contained in:
chenxiaoxi
2021-05-25 18:06:45 +08:00
parent 02698d6dab
commit f54a8d4fa1
1367 changed files with 540755 additions and 21713 deletions
@@ -0,0 +1,72 @@
<template>
<!-- <div>-->
<!-- </div>-->
<el-col :span="span">
<el-form-item
:label="config.attrName"
:title="config.attrName"
:prop="config.attrField"
label-width="150px"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-date-picker
:value="value"
type="date"
:editable="true"
:disabled="disabled"
:placeholder="placeholder"
@input="handleChange"
>
</el-date-picker>
</el-form-item>
</el-col>
</template>
<script>
export default {
name: 'CusTomDataPicker',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
}
},
computed: {
placeholder () {
return `请选择${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
isString (str) {
return (typeof str === 'string') && str.constructor === String
}
},
methods: {
handleChange (value) {
// const value = event.target.value
this.$emit('input', value)
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,190 @@
<!-- 多选时间组件 -->
<template>
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
v-show="false"
:value="value"
:placeholder="placeholder"
:disabled="disabled"
clearable
></el-input>
<div class="date-picker-group" v-if="!disabled">
<template v-for="(tag, index) in tagList">
<transition name="el-zoom-in-center">
<div class="tag-wrap" v-if="tagAnimateList.includes(tag)" :key="index">
<el-tag
size="small"
:closable="!disabled"
@close="handleRemoveTag(index)">{{ tag }}</el-tag>
</div>
</transition>
</template>
<div class="tag-wrap" v-if="datePickerVisible">
<el-date-picker
ref="datePicker"
v-model="datePickerVal"
type="date"
:disabled="disabled"
:placeholder="placeholder"
format="yyyy-MM-dd"
:picker-options="pickerOptions"
@input="handleChange"
>
</el-date-picker>
</div>
<div class="tag-wrap" v-else>
<el-button
class="add-date"
type="primary"
plain
size="mini"
@click="handleAddDate">增加日期</el-button>
</div>
</div>
<div class="date-picker-group" v-else>
<template v-for="(tag, index) in tagList">
<transition name="el-zoom-in-center">
<div class="tag-wrap" v-if="tagAnimateList.includes(tag)" :key="index">
<el-tag
size="small"
:closable="!disabled"
@close="handleRemoveTag(index)">{{ tag }}</el-tag>
</div>
</transition>
</template>
</div>
</el-form-item>
</el-col>
</template>
<script>
export default {
name: 'CusTomDataPickerGroup',
mixins: [],
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
labelWidth: {
type: String,
default: '150px'
}
},
components: {},
data () {
return {
datePickerVal: '',
tagList: [],
datePickerVisible: false,
tagAnimateList: []
}
},
methods: {
handleChange (value) {
const val = this.$dateFormat(value, 'yyyy-MM-dd')
this.tagList.push(val)
this.datePickerVisible = false
this.datePickerVal = ''
this.$emit('input', this.tagList.join(','))
},
handleAddDate () {
this.datePickerVisible = true
this.$nextTick(() => {
this.$refs.datePicker.focus()
})
},
handleRemoveTag (index) {
this.tagList.splice(index, 1)
this.$emit('input', this.tagList.join(','))
}
},
computed: {
placeholder () {
return `请选择${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
isString (str) {
return (typeof str === 'string') && str.constructor === String
},
pickerOptions () {
const _this = this
return {
disabledDate (time) {
return _this.tagList.includes(_this.$dateFormat(time, 'yyyy-MM-dd'))
}
}
}
},
watch: {
value (val) {
this.tagList = val !== '' && val !== null ? val.split(',') : []
},
tagList: {
handler (val) {
setTimeout(() => {
this.tagAnimateList = JSON.parse(JSON.stringify(val))
})
}
}
},
mounted () {
this.tagList = this.value !== '' && this.value !== null && typeof (this.value) !== 'undefined' ? this.value.split(',') : []
}
}
</script>
<style lang="less" scoped>
.add-form-item {
height: auto;
min-height: 50px;
.date-picker-group {
min-height: 49px;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
padding-left: 10px;
.tag-wrap {
height: 50px;
display: inline-flex;
align-items: center;
margin-right: 5px;
user-select: none;
&:last-child {
margin-right: 0;
}
}
.add-date {
height: 24px;
padding: 0 8px;
line-height: 22px;
}
}
}
</style>
@@ -0,0 +1,272 @@
<!-- 多选时间和可选N/A和TBD组件 -->
<template>
<el-col :span="span" class="date-picker-group-with-text">
<div class="wrap">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
:title="config.attrName"
>
<template v-if="radioValue === '1'">
<el-input
v-show="false"
:value="value"
:placeholder="placeholder"
:disabled="disabled"
clearable
></el-input>
<div class="date-picker-group" v-if="!disabled">
<template v-for="(tag, index) in tagList">
<transition name="el-zoom-in-center" :key="index">
<div class="tag-wrap" v-if="tagAnimateList.includes(tag)" :key="index">
<el-tag
size="small"
:closable="!disabled"
@close="handleRemoveTag(index)">{{ tag }}</el-tag>
</div>
</transition>
</template>
<template v-if="!['EOPSSRQ'].includes(config.attrField) || tagList.length < 1">
<div class="tag-wrap" v-if="datePickerVisible">
<el-date-picker
ref="datePicker"
v-model="datePickerVal"
type="date"
:disabled="disabled"
:placeholder="placeholder"
format="yyyy-MM-dd"
:picker-options="pickerOptions"
@input="handleChange"
>
</el-date-picker>
</div>
<div class="tag-wrap tag-wrap-btn-box" v-else>
<el-button
class="add-date"
type="primary"
plain
size="mini"
@click="handleAddDate">增加日期</el-button>
</div>
</template>
</div>
<div class="date-picker-group" v-else>
<template v-for="(tag, index) in tagList">
<transition name="el-zoom-in-center" :key="index">
<div class="tag-wrap" v-if="tagAnimateList.includes(tag)" :key="index">
<el-tag
size="small"
:closable="!disabled"
@close="handleRemoveTag(index)">{{ tag }}</el-tag>
</div>
</transition>
</template>
</div>
</template>
<template v-else>
<el-input
:value="value"
v-if="radioValue !== '1'"
disabled
/>
</template>
</el-form-item>
</div>
<div class="warp">
<el-form-item label-width="10px">
<el-radio-group :value="radioValue" :disabled="disabled">
<el-radio label="1" @click.native="handleRadioChange('1')">时间</el-radio>
<el-radio label="N/A" @click.native="handleRadioChange('N/A')">N/A</el-radio>
<el-radio label="TBD" @click.native="handleRadioChange('TBD')">TBD</el-radio>
<el-radio label="已实施" @click.native="handleRadioChange('已实施')">已实施</el-radio>
</el-radio-group>
</el-form-item>
</div>
</el-col>
</template>
<script>
import moment from 'moment'
// 用于显示相关字段
export const formatText = (str) => {
if (moment(str).isValid()) {
return moment(str).format('YYYY-MM-DD')
} else {
return str
}
}
export default {
name: 'CusTomDataPickerGroup',
mixins: [],
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
labelWidth: {
type: String,
default: '150px'
}
},
components: {},
data () {
return {
datePickerVal: '',
tagList: [],
datePickerVisible: false,
tagAnimateList: []
}
},
methods: {
handleChange (value) {
const val = this.$dateFormat(value, 'yyyy-MM-dd')
this.tagList.push(val)
this.datePickerVisible = false
this.datePickerVal = ''
this.$emit('input', this.tagList.join(','))
},
handleAddDate () {
if (this.tagList.length === 10) {
this.$message({
message: '日期选择上限为10个',
type: 'warning'
})
} else {
this.datePickerVisible = true
this.$nextTick(() => {
this.$refs.datePicker.focus()
})
}
},
handleRemoveTag (index) {
this.tagList.splice(index, 1)
this.$emit('input', this.tagList.join(','))
},
// 时间、N/A、TBD切换事件
handleRadioChange (val) {
switch (val) {
case '1':
this.$emit('input', '')
break
case 'N/A':
this.$emit('input', 'N/A')
break
case 'TBD':
this.$emit('input', 'TBD')
break
case '已实施':
this.$emit('input', '已实施')
break
}
}
},
computed: {
placeholder () {
return `请选择${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
isString (str) {
return (typeof str === 'string') && str.constructor === String
},
pickerOptions () {
const _this = this
return {
disabledDate (time) {
return _this.tagList.includes(_this.$dateFormat(time, 'yyyy-MM-dd'))
}
}
},
radioValue () {
const value = this.value
if (value === 'N/A' || value === 'TBD' || value === '已实施') {
return value
} else {
return '1'
}
}
},
watch: {
value (val) {
this.tagList = val !== '' && val !== null && val !== undefined ? val.split(',') : []
},
tagList: {
handler (val) {
setTimeout(() => {
this.tagAnimateList = JSON.parse(JSON.stringify(val))
})
}
}
},
mounted () {
this.tagList = this.value !== '' && this.value !== null && typeof (this.value) !== 'undefined' ? this.value.split(',') : []
}
}
</script>
<style lang="less" scoped>
.date-picker-group-with-text {
display: flex;
.wrap {
&:first-child {
flex: 1;
overflow: hidden;
}
}
}
.add-form-item {
height: auto;
min-height: 50px;
/deep/.el-form-item{
margin-bottom: 0;
}
.date-picker-group {
min-height: 49px;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
padding-left: 10px;
.tag-wrap {
height: 50px;
display: inline-flex;
align-items: center;
margin-right: 5px;
user-select: none;
&:last-child {
margin-right: 0;
}
}
.tag-wrap-btn-box{
.add-date {
height: 24px;
padding: 0 8px;
line-height: 22px;
}
}
}
/deep/.el-form-item__error{
right: 0 !important;
}
}
</style>
@@ -0,0 +1,152 @@
<template>
<!-- <div>-->
<!-- </div>-->
<el-col :span="span" class="date-picker-with-text">
<div class="wrap">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
:title="config.attrName"
>
<el-datePicker
v-if="radioValue === '1'"
:value="value"
type="date"
:editable="true"
:disabled="disabled"
:placeholder="placeholder"
@input="handleChange"
></el-datePicker>
<el-input
:value="value"
v-if="radioValue !== '1'"
disabled
/>
</el-form-item>
</div>
<div class="warp">
<el-form-item label-width="10px">
<el-radio-group :value="radioValue" :disabled="disabled">
<el-radio label="1" @click.native="handleRadioChange('1')">时间</el-radio>
<el-radio label="N/A" @click.native="handleRadioChange('N/A')">N/A</el-radio>
<el-radio label="TBD" @click.native="handleRadioChange('TBD')">TBD</el-radio>
<el-radio label="已实施" @click.native="handleRadioChange('已实施')">已实施</el-radio>
</el-radio-group>
</el-form-item>
</div>
</el-col>
</template>
<script>
export default {
name: 'DatePickerWithText',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
labelWidth: {
type: String,
default: '150px'
}
},
data() {
return {
// radioValue: ''
}
},
computed: {
placeholder () {
return `请选择${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
isString (str) {
return (typeof str === 'string') && str.constructor === String
},
radioValue() {
const value = this.value
if (value === 'N/A' || value === 'TBD' || value === '已实施') {
return value
} else {
return '1'
}
}
},
watch: {
value: {
immediate: true,
handler: (newValue, oldValue) => {
// console.log(newValue)
// if (newValue === 'N/A') {
// this.radioValue = 'N/A'
// } else if (newValue === 'TBD') {
// this.radioValue = 'TBD'
// } else {
// this.radioValue = '1'
// }
}
}
},
methods: {
handleChange (value) {
// const value = event.target.value
this.$emit('input', this.$moment(value).format('YYYY-MM-DD'))
},
handleRadioChange (val) {
switch (val) {
case '1':
this.$emit('input', '')
break
case 'N/A':
this.$emit('input', 'N/A')
break
case 'TBD':
this.$emit('input', 'TBD')
break
case '已实施':
this.$emit('input', '已实施')
break
}
}
}
}
</script>
<style lang="less" scoped>
.date-picker-with-text {
display: flex;
.wrap {
&:first-child {
flex: 1;
overflow: hidden;
}
}
}
/deep/.el-form-item{
margin-bottom: 0;
}
/deep/.el-form-item__error{
right: 0 !important;
left: 100px !important;
}
</style>
@@ -0,0 +1,152 @@
<template>
<!-- <div>-->
<!-- </div>-->
<el-col :span="span" class="date-picker-with-text">
<div class="wrap">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
:title="config.attrName"
>
<el-datePicker
v-if="radioValue === '1'"
:value="value"
type="date"
:editable="true"
:disabled="disabled"
:placeholder="placeholder"
@input="handleChange"
></el-datePicker>
<el-input
:value="value"
v-if="radioValue !== '1'"
disabled
/>
</el-form-item>
</div>
<div class="warp">
<el-form-item label-width="10px">
<el-radio-group :value="radioValue" :disabled="disabled">
<el-radio label="1" @click.native="handleRadioChange('1')">时间</el-radio>
<el-radio label="已发布" @click.native="handleRadioChange('已发布')">已发布</el-radio>
<el-radio label="TBD" @click.native="handleRadioChange('TBD')">TBD</el-radio>
</el-radio-group>
</el-form-item>
</div>
</el-col>
</template>
<script>
export default {
name: 'DatePickerWithText2',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
labelWidth: {
type: String,
default: '150px'
}
},
data() {
return {
// radioValue: ''
}
},
computed: {
placeholder () {
return `请选择${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
isString (str) {
return (typeof str === 'string') && str.constructor === String
},
radioValue() {
const value = this.value
if (value === '已发布' || value === 'TBD') {
return value
} else {
return '1'
}
}
},
watch: {
value: {
immediate: true,
handler: (newValue, oldValue) => {
// console.log(newValue)
// if (newValue === 'N/A') {
// this.radioValue = 'N/A'
// } else if (newValue === 'TBD') {
// this.radioValue = 'TBD'
// } else {
// this.radioValue = '1'
// }
}
}
},
methods: {
handleChange (value) {
if (value) {
this.$emit('input', this.$moment(value).format('YYYY-MM-DD'))
} else {
this.$emit('input', '')
}
},
handleRadioChange (val) {
switch (val) {
case '1':
this.$emit('input', '')
break
case '已发布':
this.$emit('validate')
this.$emit('input', '已发布')
break
case 'TBD':
this.$emit('validate')
this.$emit('input', 'TBD')
break
}
}
}
}
</script>
<style lang="less" scoped>
.date-picker-with-text {
display: flex;
.wrap {
&:first-child {
flex: 1;
overflow: hidden;
}
}
}
/deep/.el-form-item{
margin-bottom: 0;
}
/deep/.el-form-item__error{
right: 0 !important;
}
</style>
@@ -0,0 +1,167 @@
<template>
<div>
<Form v-if="reload" ref="sarStandardsInfoForm" :model="sarStandardsInfoEO" :rules="rules" class="label-input-form">
<template v-for="item in formFieldList">
<template v-if="item.attrType === 'INPUT_STR'">
<custom-input :key="item.attrField" :config="item" v-model="sarStandardsInfoEO[item.attrField]"></custom-input>
</template>
<template v-else-if="item.attrType === 'DATE_PICKER'">
<custom-date-pick :key="item.attrField" :config="item" v-model="sarStandardsInfoEO[item.attrField]"></custom-date-pick>
</template>
<template v-else-if="item.attrType === 'FILE'">
<custom-file :key="item.attrField" :config="item" v-model="sarStandardsInfoEO[item.attrField]"></custom-file>
</template>
<template v-else-if="item.attrType === 'TEXTAREA'">
<custom-textarea :key="item.attrField" :config="item" v-model="sarStandardsInfoEO[item.attrField]"></custom-textarea>
</template>
</template>
<button @click="jiaoyan">aaaaa</button>
</Form>
</div>
</template>
<script>
import CustomInput from './Input'
import CustomTextarea from './Textarea'
import CustomSearchSelect from './SearchSelect'
import CustomDatePick from './DatePicker'
import CustomFile from './File'
export default {
name: 'Example',
components: {
CustomFile,
CustomInput,
CustomTextarea,
CustomSearchSelect,
CustomDatePick
},
data () {
return {
reload: true,
sarStandardsInfoEO: {
TEST_AA: new Date(1602518400000)
},
formFieldList: [
{
'id': 'BR8CW5Z8ERZXSMQ9QPE7',
'attrField': 'TEST',
'attrName': '测试1',
'attrType': 'INPUT_STR',
'orderNum': 1,
'isEdit': '0',
'creationUser': 'WY8J26MH23',
'validFlag': '0',
'creationTime': '2020-10-11',
'modifyTime': '2020-10-11',
'attrLen': 100,
'attrValue': null,
'isMust': '1',
'isShowImp': '0',
'showRegionId': '1'
},
{
'id': 'TKLUW3KLVYJHMWFTFY7U',
'attrField': 'TEST_AA',
'attrName': '测试2',
'attrType': 'DATE_PICKER',
'orderNum': 2,
'isEdit': '0',
'creationUser': 'WY8J26MH23',
'validFlag': '0',
'creationTime': '2020-10-11',
'modifyTime': '2020-10-11',
'attrLen': 10,
'attrValue': null,
'isMust': '0',
'isShowImp': '0',
'showRegionId': '3'
},
{
'id': '89EYDA3XNBJBS7368LR6',
'attrField': 'TEST_BB',
'attrName': '测试3',
'attrType': 'FILE',
'orderNum': 3,
'isEdit': '0',
'creationUser': 'WY8J26MH23',
'validFlag': '0',
'creationTime': '2020-10-11',
'modifyTime': '2020-10-11',
'attrLen': 500,
'attrValue': null,
'isMust': '1',
'isShowImp': '0',
'showRegionId': '5'
},
{
'id': 'CB2W6LMLSH3D4V27ZL9A',
'attrField': 'TEST_CC',
'attrName': '测试4',
'attrType': 'TEXTAREA',
'orderNum': 4,
'isEdit': '0',
'creationUser': 'WY8J26MH23',
'validFlag': '0',
'creationTime': '2020-10-11',
'modifyTime': '2020-10-11',
'attrLen': 500,
'attrValue': null,
'isMust': '1',
'isShowImp': '0',
'showRegionId': '4'
}
],
rules: {}
}
},
mounted () {
this.resolveFormFieldListRules()
console.log(this.$dateFormat(1602518400000, 'yyyy-MM-dd hh:mm:ss'))
},
methods: {
/**
* 生成校验规则
*/
resolveFormFieldListRules () {
this.reload = false
const formFieldList = this.formFieldList
const rules = {}
formFieldList.forEach((item) => {
const rule = []
if (item.isMust === '0' && item.attrType !== 'DATE_PICKER') {
rule.push({ required: true, message: `${item.attrName}不能为空`, trigger: 'blur' })
}
if (item.isMust === '0' && item.attrType === 'DATE_PICKER') {
rule.push({required: true, type: 'date', message: `${item.attrName}不能为空`, trigger: 'change'})
}
if (item.attrLen && item.attrType !== 'DATE_PICKER' && item.attrType !== 'SEL_OPTION') {
rule.push({type: 'string', max: item.attrLen, message: `${item.attrName}不能超过${item.attrLen}个字符`, trigger: 'blur'})
}
if (rule.length > 0) {
// this.$set(this.rules, item.attrField, rule)
rules[item.attrField] = rule
}
})
// this.rules = rules
this.$set(this, 'rules', rules)
setTimeout(() => {
this.reload = true
}, 1)
// this.$nextTick(() => {
// this.$refs['sarStandardsInfoForm'].resetFields()
// })
},
jiaoyan () {
this.$refs['sarStandardsInfoForm'].validate((valid) => {
console.log(valid)
})
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,460 @@
<template>
<!-- <div>-->
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<ul class="file-file__wrap" v-if="showFileModel">
<li class="file-item"
v-for="(file, index) in showFileList"
:key="index"
:title="file.name"
@click="handlePreview(file)">{{ file.name }}</li>
<el-button
size="small"
@click="clickButtonToUpload('opinionFileList')"
icon="el-icon-upload"
class="form-upload-btn"
v-if="reUpload || showUploadBtn">{{ uploadText || '重新上传' }}</el-button>
</ul>
<template style="margin-left: 105px;" v-else>
<el-button
size="small"
@click="clickButtonToUpload('opinionFileList')"
icon="el-icon-upload"
class="form-upload-btn"
>
{{ (value === 'null' || value === '' || value == null) && (!processModel || (processModel && !disabled)) ? '点击上传' : '查看已上传的文件' }}
</el-button>
</template>
<el-dialog
width='400px'
:visible.sync="importModalshowflagtemp"
:title="processModel && disabled ? '查看已上传的文件' : (title || '导入文件')"
:footer-hide="true"
append-to-body
>
<el-upload
class="customer-upload"
:class="{'disabled': disabled}"
multiple
drag
:show-file-list="showUploadlist"
:on-success="uploadSuccess"
:before-upload="beforeUpload"
:on-remove="removeOneFile"
:action="uploadPath"
:limit="limit"
:on-exceed="handleExceed"
:on-preview="handlePreview"
name="file"
:file-list="defaultFileList"
:disabled="disabled"
ref="importFileAboutStand">
<i :class="iconClass"></i>
<div class="el-upload__text">{{ tips }}</div>
</el-upload>
</el-dialog>
</el-form-item>
</el-col>
<!-- </div>-->
</template>
<script>
import { getConvertFileByAttId } from 'api/process'
export default {
name: 'CustomFile',
data() {
return {
showUploadlist: true, // 导入过程中新增数据时,如果数据错误,不出现导入列表
uploadPath: 'api/att/attFile/upload',
defaultFileList: [], // 默认显示
showFileList: [],
importModalshowflagtemp: false
}
},
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 指定允许上传的类型
allowType: {
type: Array,
default: () => {
return ['.pdf', '.PDF', '.doc','.DOC', '.docx','.DOCX', '.pptx', '.PPTX', '.ppt', '.PPT', '.jpg','.JPG','.jpeg','.JPEG', '.PNG', '.png', '.xls','.XLS', '.xlsx','.XLSX']
}
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 是否为流程使用
processModel: {
type: Boolean,
default: false
},
labelWidth: {
type: String,
default: '150px'
},
// 点击文件在线预览
preview: {
type: Boolean,
default: false
},
// 是否可重新上传
reUpload: {
type: Boolean,
default: false
},
limit: {
type: Number,
default: 8
},
exceed: {
type: String
},
// 只展示上传的文件,不展示查看已上传的文件按钮
showFileModel: {
type: Boolean,
default: false
},
uploadText: {
type: String
},
showUploadBtn: {
type: Boolean
}
},
watch: {
value: {
handler(val) {
if (this.showFileModel) {
this.getShowFileList()
}
}
}
},
mounted() {
if (this.showFileModel) {
this.getShowFileList()
}
},
computed: {
placeholder() {
return `请输入${this.config.attrName}`
},
showMessage() {
return `${this.config.attrName}不能为空`
},
isRequired() {
return !!this.config.isMust
},
title() {
return this.config.title
},
tips() {
if (this.processModel && this.reUpload) {
return '点击重新上传附件'
} else if (this.processModel && this.disabled && this.preview) {
return '点击名称在线查看'
} else if (this.processModel && this.disabled) {
return '点击名称下载附件'
} else {
return '点击或拖拽上传文件'
}
},
iconClass() {
if (this.processModel && this.reUpload) {
return 'el-icon-upload'
} else if (this.processModel && this.disabled && this.preview) {
return 'el-icon-view'
} else if (this.processModel && this.disabled) {
return 'el-icon-download'
} else {
return 'el-icon-upload'
}
}
},
methods: {
handleExceed(files, fileList) {
if (this.exceed) {
this.$message.warning(this.exceed)
} else {
this.$message.warning(`当前限制选择 ${this.limit} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
}
},
beforeUpload(file) {
var filename = file.name
var index1 = filename.lastIndexOf('.')
var index2 = filename.length
var fileSuffix = filename.substring(index1, index2)
fileSuffix = fileSuffix.toLocaleLowerCase()
// 判断上传文件格式
if (!this.allowType.includes(fileSuffix)) {
this.$message.error(`文件${file.name}格式不正确,请上传${this.allowType.join('、')}文件`)
return false
}
// 判断文件上传大小
if (file.size / 1024 / 1024 > 200) {// eslint-disable-line
this.$message.error('文件' + file.name + '大小不超过200M')
return false
}
return true
},
handleChange(event) {
const value = event.target.value
this.$emit('input', value)
},
clickButtonToUpload(current) {
this.importModalshowflagtemp = true
this.$refs.importFileAboutStand && this.$refs.importFileAboutStand.clearFiles()
this.defaultFileList = []
if (this.value === 'null' || this.value == null) {
// this.value = ''
this.$emit('input', '')
}
let fileList
if (this.value != null && this.value !== '') {
let paramefile = this.value
if (paramefile.charAt(paramefile.length - 1) === ',') {
paramefile = paramefile.substring(0, paramefile.length - 1)
}
this.$http.get('att/attFile/getMultiFileInfos', {
fileIds: paramefile
}, {
_this: this
}, res => {
fileList = res.data
if (fileList != null && fileList.length > 0) {
for (let i = 0; i < fileList.length; i++) {
let obj = {name: '', response: {}}
obj.name = fileList[i].oldFileName
obj.response.data = fileList[i]
this.defaultFileList.push(obj)
}
}
}, e => {
})
}
},
uploadSuccess(res, file, fileList) {
if (res.ok) {
// this.value += res.data.id + ','
this.$emit('input', this.value + res.data.id + ',')
this.$emit('success')
this.$message({
message: '文件上传成功',
type: 'success'
})
switch (this.config.attrField) {
case 'recordsAttr':
this.$emit('recordsAttrTime', res.data.uploadTime)
break
case 'signAttr':
this.$emit('signAttrTime', res.data.uploadTime)
break
case 'otherAttr':
this.$emit('otherAttrTime', res.data.uploadTime)
break
}
// 国内外标准法规返回文件上传成功状态
this.$emit('fileSuccess', true)
// this.importModalshowflagtemp = false
} else {
this.$message({
message: res.message,
type: 'error'
})
fileList.pop()
}
},
removeOneFile(file, fileList) {
const value = this.value
let ids = value.split(',')
if (file.response) {
let fileIds = file.response.data.id
let newIdList = this.removeArray(ids, fileIds)
let newStr = ''
if (newIdList != null && newIdList.length > 0) {
for (let i = 0; i < newIdList.length; i++) {
if (newIdList[i] !== '') {
newStr += newIdList[i] + ','
}
}
this.$emit('input', newStr)
} else {
this.$emit('input', '')
}
}
const showFileList = []
fileList.map(item => {
let obj = {name: '', response: {}}
obj.name = item.response.data.oldFileName
obj.response.data = item.response.data
showFileList.push(obj)
})
this.showFileList = showFileList
},
// 删除数组中的某个对象
removeArray(_arr, _obj) {
var length = _arr.length
for (var i = 0; i < length; i++) {
if (_arr[i] === _obj) {
if (i === 0) {
_arr.shift() // 删除并返回数组的第一个元素
return _arr
} else if (i === length - 1) {
_arr.pop() // 删除并返回数组的最后一个元素
return _arr
} else {
_arr.splice(i, 1) // 删除下标为i的元素
return _arr
}
}
}
},
// 文件预览
handlePreview(file) {
const attId = file.response.data.id
if (this.preview) {
this.getConvertFileByAttId(attId)
.then(res => {
switch (res.convertState) {
case 'ERROR':
this.$message.warning('文档转换失败')
break
case 'LODING':
this.$message.info('文档转换中,请稍后查看')
break
case 'SUCCESS':
const { convertFileInfo } = res
window.open('/static/pdf/web/viewer.html?file=' + encodeURIComponent('/api/att/attFile/getFileInfo?fileId=' + convertFileInfo.id))
break
}
}).catch(e => {
this.$message.warning('文档转换失败')
})
} else {
if (attId) {
window.location.href = '/api/att/attFile/downloadFileForSar?fileId=' + attId
} else {
this.$message.warning('文件不存在,下载失败')
}
}
},
// 读取文档转换后的文件
getConvertFileByAttId(attId) {
return new Promise((resolve, reject) => {
getConvertFileByAttId({
attId
}).then(res => {
if (res.ok && res.data.convertState) {
resolve(res.data)
} else {
reject()
}
}).catch(e => {
reject(e)
})
})
},
/**
* @description: 获取展示的文件
* @author: chenxiaoxi
* @time: 2021-03-30 17:03:36
*/
getShowFileList() {
return new Promise((resolve, reject) => {
if (this.value && this.value !== '') {
let paramefile = this.value
if (paramefile.charAt(paramefile.length - 1) === ',') {
paramefile = paramefile.substring(0, paramefile.length - 1)
}
this.$http.get('att/attFile/getMultiFileInfos', {
fileIds: paramefile
}, {
_this: this
}, res => {
const fileList = res.data, showFileList = []
if (fileList && fileList.length) {
fileList.map(file => {
let obj = {name: '', response: {}}
obj.name = file.oldFileName
obj.response.data = file
showFileList.push(obj)
})
}
this.showFileList = showFileList
resolve()
}, e => {
})
}
})
}
}
}
</script>
<style lang="less" scoped>
.customer-upload {
&.disabled {
/deep/ .el-upload-dragger {
.el-upload__text {
color: #ccc;
}
&:hover {
cursor: not-allowed;
border-color: #d9d9d9;
}
}
}
}
/deep/ .el-form-item__error {
right: 150px !important;
}
/deep/ .el-upload-dragger {
[class^="el-icon-"] {
font-size: 67px;
color: #C0C4CC;
margin: 40px 0 16px;
line-height: 50px;
}
}
.file-file__wrap {
position: relative;
& > li{
width: calc(~'100% - 100px');
}
}
.file-item {
color: rgba(64, 158, 255, 0.8);
height: 50px;
line-height: 50px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&:hover {
cursor: pointer;
color: rgba(64, 158, 255, 1);
}
}
</style>
@@ -0,0 +1,72 @@
<template>
<!-- <div>-->
<!-- </div>-->
<el-col :span="span">
<el-form-item
:label="config.attrName"
:title="config.attrName"
:prop="config.attrField"
label-width="155px"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-date-picker
:value="value"
type="date"
:editable="true"
:disabled="true"
:placeholder="placeholder"
@input="handleChange"
>
</el-date-picker>
</el-form-item>
</el-col>
</template>
<script>
export default {
name: 'CusTomDataPicker',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
}
},
computed: {
placeholder () {
return `请选择${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
isString (str) {
return (typeof str === 'string') && str.constructor === String
}
},
methods: {
handleChange (value) {
// const value = event.target.value
this.$emit('input', value)
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,69 @@
<template>
<!-- <div>-->
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
label-width="150px"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
:value="value"
:placeholder="placeholder"
:disabled="disabled"
clearable
@input="handleChange"
></el-input>
</el-form-item>
</el-col>
<!-- </div>-->
</template>
<script>
export default {
name: 'CustomInput',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
}
},
methods: {
handleChange (event) {
// const value = event.target.value
const value = event
console.log(value)
this.$emit('input', value)
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,334 @@
<template>
<div>
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
:value="value"
:placeholder="placeholder"
:disabled="disabled"
clearable
@input="handleChange"
></el-input>
<el-button
type="primary"
class="common-button-primary"
round
style="position:absolute;top: 10px;right: 0;"
@click="selectLaws"
v-if="(processModel && !disabled) || !processModel"
>{{config.attrField === 'releventStand' ? '选择标准' :'手动查找'}}</el-button>
</el-form-item>
<el-dialog
:title="config.attrName"
:visible.sync="replaceLawsNumModel"
width="875px"
:close-on-click-modal="false"
@close="replaceLawsNumModelCancel"
:append-to-body="true"
>
<div class="search-area">
<div class="left">
<el-form :modal="replaceLawsNumForm" :inline="true" class="label-input-form" @keyup.enter.native="getReplaceLawsNumRowInfo">
<el-form-item label="编号/名称" class="search-item">
<el-input v-model="replaceLawsNumForm.standNumber" placeholder="根据编号/名称查找" clearable :maxlength="100"></el-input>
</el-form-item>
<el-form-item label="国内/海外" class="search-item">
<el-select
v-model="replaceLawsNumForm.standType"
placeholder="请选择"
>
<el-option value="ALL" label="全部"></el-option>
<el-option value="INLAND" label="国内"></el-option>
<el-option value="FOREIGN" label="海外"></el-option>
</el-select>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
icon="el-icon-search"
type="primary"
class="common-button-primary"
round
@click="getReplaceLawsNumRowInfo">
</el-button>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
class="common-button-default"
icon="el-icon-refresh-left"
round
type="default"
@click="getResetLawsNumRow"></el-button>
</el-form-item>
</el-form>
</div>
</div>
<el-table
ref="selections"
:data="replaceLawsNumRow"
tooltip-effect="dark"
style="width: 100%;overflow-y: auto;overflow-x: hidden;"
border
:height="300"
:header-cell-style="{background: '#e8e8e8', color: '#333333', fontSize: '16px',
fontWeight: 'bold', height: '48px'}"
@selection-change="selectReplaceStandNumRowChange">
<el-table-column
type="selection"
width="55"
align="center">
</el-table-column>
<el-table-column
label="标准编号"
width="130">
<template slot-scope="scope">
<a v-if="scope.row.standYear" @click="handlePreview(scope.row)">{{ scope.row.standSort }} {{ scope.row.standNumber }}-{{ scope.row.standYear }}</a>
<a v-else @click="handlePreview(scope.row)">{{ scope.row.standSort }} {{ scope.row.standNumber }}</a>
</template>
</el-table-column>
<el-table-column
prop="standName"
label="标准名称"
width="130">
</el-table-column>
<el-table-column
prop="issueTime"
label="发布日期"
width="130">
</el-table-column>
<el-table-column
prop="putTime"
label="实施日期"
width="130">
</el-table-column>
<el-table-column
prop="standNatureShow"
label="标准性质"
width="130">
</el-table-column>
<el-table-column
prop="standStateShow"
label="标准状态"
width="130">
</el-table-column>
</el-table>
<loading :loading="replaceLoading">{{$t('m.dataAcquisition')}}</loading>
<!--分页-->
<pagination
style="position: relative;"
:page="replacePage"
:total="replaceTotal"
@pageChange="pageChangeReplace"
@pageSizeChange="pageSizeChangeReplace"></pagination>
<div slot="footer" class="demo-drawer-footer">
<el-button round class="common-button-default" icon="el-icon-close" @click="replaceLawsNumModel = false">取消</el-button>
<el-button type="primary" round class="common-button-primary" icon="el-icon-check" @click="replaceLawsNumModelBt">提交</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: 'CustomInput',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 是否为流程中使用
processModel: {
type: Boolean,
default: false
},
// label宽度
labelWidth: {
type: String,
default: '150px'
}
},
data () {
return {
replaceLawsNumModel: false,
sarBussionessLawsEO: {
replaceLawsNum: ''
},
// 代替标准号
replaceLawsNumForm: {
standNumber: '', // 政策编号
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
standType: 'ALL',
quoteIdList: '',
validFlag: '0',
menuId: 'nomenu'
},
replaceLawsNumRow: [], // 代替政策号 数组内容
replaceTotal: 0,
selectedListRep: [],
replaceLoading: true,
replacePage: 1
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
}
},
methods: {
handleChange (event) {
// const value = event.target.value
const value = event
console.log(value)
this.$emit('input', value)
},
selectLaws () {
// if (this.standNumFlag === 1) {
// this.$refs.selections.selectAll(false)
// }
// this.sarBussionessLawsEO.replaceLawsNum = ''
this.replaceLawsNumModel = true
this.getReplaceLawsNumRow()
},
getReplaceLawsNumRowInfo() {
this.replaceLawsNumForm.page = 1
this.getReplaceLawsNumRow()
},
// 代替政策号 请求数据
getReplaceLawsNumRow () {
if (this.sarBussionessLawsEO.replaceLawsNum !== null && this.sarBussionessLawsEO.replaceLawsNum !== '') {
this.replaceLawsNumForm.quoteIdList = this.quoteIdList1.toString() === '' ? '' : this.quoteIdList1
} else {
this.quoteIdList1 = []
this.replaceLawsNumForm.quoteIdList = ''
}
this.$http.get('lawss/sarStandardsInfo/getSarStandardsInfoPage', this.replaceLawsNumForm, {
_this: this,
loading: 'replaceLoading'
}, res => {
this.replaceLawsNumRow = res.data.list
this.replaceTotal = res.data.count
if (this.selectedListRep.length !== 0) {
this.selectedListRep.map((list) => {
this.replaceLawsNumRow.map((item) => {
if (list.id === item.id) {
item._checked = true
}
})
})
}
}, e => {
})
},
// 代替政策编号-取消
replaceLawsNumModelCancel () {
// this.replaceLawsNumModel = false
this.$refs.selections.clearSelection()
},
// 代替政策号 table选择事件
selectReplaceStandNumRowChange (row) {
this.selectedListRep = row
},
// 代替政策分页
pageChangeReplace (page) {
this.replacePage = page
this.replaceLawsNumForm.page = page
this.getReplaceLawsNumRow()
},
pageSizeChangeReplace (pageSize) {
// this.replaceRows = pageSize
this.replaceLawsNumForm.pageSize = pageSize
this.getReplaceLawsNumRow()
},
// 代替政策编号确定
replaceLawsNumModelBt () {
let textArr = []
if (typeof this.value === 'string') {
if (this.value) {
textArr = this.value.split(',')
}
}
if (this.selectedListRep.length === 0) {
return this.$message({
message: '请先选择数据',
type: 'warning'
})
}
if (this.selectedListRep.length + textArr.length > 20) {
return this.$message({
message: '代替标准号最多选择20项',
type: 'warning'
})
}
this.selectedListRep.map((item) => {
let texts = ''
if (item.standYear != null && item.standYear !== '') {
texts = item.standSort !== null ? item.standSort + ' ' + item.standNumber + '-' + item.standYear : item.standNumber + '-' + item.standYear
} else {
texts = item.standSort !== null ? item.standSort + ' ' + item.standNumber : item.standNumber
}
textArr.push(texts)
textArr = [...new Set(textArr)]
this.replaceLawsNumModel = false
})
// this.SarLawsInfoEO.replaceLawsNum = textArr.join(',')
this.$emit('input', textArr.join(','))
this.$refs.selections.clearSelection()
},
// 点击查看
handlePreview (item) {
console.log('看看看看看看看看item', item)
let routeUrl = this.$router.resolve({
name: 'OtherBussStandardDetails',
params: {
id: item.id,
pageType: 'BUSINESS_STAND'
}
})
window.open(routeUrl.href, '_blank')
},
getResetLawsNumRow () {
this.replaceLawsNumForm = {
standNumber: '', // 政策编号
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
standType: 'ALL',
quoteIdList: '',
validFlag: '0'
}
this.getReplaceLawsNumRow()
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,378 @@
<template>
<!-- <div>-->
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
:value="value"
:maxlength="maxlength"
:placeholder="placeholder"
:disabled="disabled"
type="textarea"
resize="none"
clearable
:autosize="true"
@input="handleChange"
></el-input>
<el-button
type="primary"
class="common-button-primary"
round
style="position:absolute;top: 10px;right: 0;"
@click="selectLaws"
v-if="(processModel && !disabled) || !processModel"
>{{config.attrField === 'releventLaws' ? '选择政策' :'手动查找'}}</el-button>
</el-form-item>
<el-dialog
:title="config.attrName"
:visible.sync="replaceLawsNumModel"
width="875px"
:close-on-click-modal="false"
@close="replaceLawsNumModelCancel"
:append-to-body="true"
>
<div class="search-area">
<div class="left">
<el-form :modal="replaceLawsNumForm" :inline="true" class="label-input-form" @keyup.enter.native="getReplaceLawsNumRowFirst">
<el-form-item label="编号/名称" class="search-item">
<el-input v-model="replaceLawsNumForm.numberName" placeholder="根据编号/名称查找" clearable :maxlength="1000"></el-input>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
icon="el-icon-search"
type="primary"
class="common-button-primary"
round
@click="getReplaceLawsNumRowFirst">
</el-button>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
class="common-button-default"
icon="el-icon-refresh-left"
round
type="default"
@click="getResetLawsNumRow"></el-button>
</el-form-item>
</el-form>
</div>
</div>
<el-table
ref="selections"
:data="replaceLawsNumRow"
tooltip-effect="dark"
style="width: 100%;overflow-y: auto;overflow-x: hidden;"
border
:height="300"
:header-cell-style="{background: '#e8e8e8', color: '#333333', fontSize: '16px',
fontWeight: 'bold', height: '48px'}"
@selection-change="selectReplaceStandNumRowChange">
<el-table-column
type="selection"
width="55"
align="center">
</el-table-column>
<el-table-column
label="政策编号"
width="130">
<template slot-scope="scope">
<a class="table-jump" @click="handlePreview(scope.row)">{{ scope.row.lawsNumber }}</a>
<!--<a v-if="scope.row.standYear" @click="handlePreview(scope.row)">{{ scope.row.standSort }} {{ scope.row.standNumber }}-{{ scope.row.standYear }}</a>-->
<!--<a v-else @click="handlePreview(scope.row)">{{ scope.row.standSort }} {{ scope.row.standNumber }}</a>-->
</template>
</el-table-column>
<el-table-column
prop="lawsName"
label="中文名称">
<template slot-scope="scope">
<a class="table-jump" @click="handlePreview(scope.row)">{{ scope.row.lawsName }}</a>
</template>
</el-table-column>
<el-table-column
prop="issueTime"
label="发布日期"
width="130">
</el-table-column>
<el-table-column
show-overflow-tooltip
prop="XCXSSRQ"
label="新车型实施日期">
<template slot-scope="scope">
<span v-if="scope.row.attrInfoMap.XCXSSRQ !== 'N/A' && scope.row.attrInfoMap.XCXSSRQ !== 'TBD'">{{ scope.row.attrInfoMap.XCXSSRQ || '' }}</span>
<span v-else>{{ scope.row.attrInfoMap.XCXSSRQ }}</span>
</template>
</el-table-column>
<el-table-column
prop="stateName"
label="文本状态">
</el-table-column>
</el-table>
<loading :loading="replaceLoading">{{$t('m.dataAcquisition')}}</loading>
<!--分页-->
<pagination
style="position: relative;"
:page="replacePage"
:total="replaceTotal"
@pageChange="pageChangeReplace"
@pageSizeChange="pageSizeChangeReplace"></pagination>
<div slot="footer" class="demo-drawer-footer">
<el-button round class="common-button-default" icon="el-icon-close" @click="replaceLawsNumModelCancel">取消</el-button>
<el-button type="primary" round class="common-button-primary" icon="el-icon-check" @click="replaceLawsNumModelBt">提交</el-button>
</div>
</el-dialog>
</el-col>
<!-- </div>-->
</template>
<script>
export default {
name: 'CustomInput',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
maxlength: {
type: Number,
required: true,
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 是否为流程中使用
processModel: {
type: Boolean,
default: false
},
// label宽度
labelWidth: {
type: String,
default: '150px'
}
},
data() {
return {
replaceLawsNumModel: false,
sarBussionessLawsEO: {
replaceLawsNum: ''
},
// 代替标准号
replaceLawsNumForm: {
numberName: '', // 政策编号
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
lawsType: 'FOREIGN',
quoteIdList: '',
menuId: ''
},
replaceLawsNumRow: [], // 代替政策号 数组内容
replaceTotal: 0,
selectedListRep: [],
replaceLoading: true,
replacePage: 1,
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
}
},
methods: {
handleChange (event) {
// const value = event.target.value
const value = event
console.log(value)
this.$emit('input', value)
if (value.length==1000){
return this.$message({
message: '相关政策不能输入超过1000个字符',
type: 'warning'
});
}
},
selectLaws () {
// if (this.standNumFlag === 1) {
// this.$refs.selections.selectAll(false)
// }
// this.sarBussionessLawsEO.replaceLawsNum = ''
this.replaceLawsNumModel = true
this.getReplaceLawsNumRow()
},
// 代替政策号 请求数据
getReplaceLawsNumRowFirst () {
if (this.sarBussionessLawsEO.replaceLawsNum !== null && this.sarBussionessLawsEO.replaceLawsNum !== '') {
this.replaceLawsNumForm.quoteIdList = this.quoteIdList1.toString() === '' ? '' : this.quoteIdList1
} else {
this.quoteIdList1 = []
this.replaceLawsNumForm.quoteIdList = ''
}
this.replaceLawsNumForm.page = 1
this.replacePage = 1
this.$http.get('lawss/sarLawsInfo/page', this.replaceLawsNumForm, {
_this: this,
loading: 'replaceLoading'
}, res => {
this.replaceLawsNumRow = res.data.list
this.replaceTotal = res.data.count
if (this.selectedListRep.length !== 0) {
this.selectedListRep.map((list) => {
this.replaceLawsNumRow.map((item) => {
if (list.id === item.id) {
item._checked = true
}
})
})
}
}, e => {
})
},
// 代替政策号 请求数据
getReplaceLawsNumRow () {
if (this.sarBussionessLawsEO.replaceLawsNum !== null && this.sarBussionessLawsEO.replaceLawsNum !== '') {
this.replaceLawsNumForm.quoteIdList = this.quoteIdList1.toString() === '' ? '' : this.quoteIdList1
} else {
this.quoteIdList1 = []
this.replaceLawsNumForm.quoteIdList = ''
}
this.$http.get('lawss/sarLawsInfo/page', this.replaceLawsNumForm, {
_this: this,
loading: 'replaceLoading'
}, res => {
this.replaceLawsNumRow = res.data.list
this.replaceTotal = res.data.count
if (this.selectedListRep.length !== 0) {
this.selectedListRep.map((list) => {
this.replaceLawsNumRow.map((item) => {
if (list.id === item.id) {
item._checked = true
}
})
})
}
}, e => {
})
},
// 代替政策编号-取消
replaceLawsNumModelCancel () {
this.replaceLawsNumModel = false
this.replaceLawsNumForm.numberName = ''
this.$refs.selections.clearSelection()
},
// 代替政策号 table选择事件
selectReplaceStandNumRowChange (row) {
this.selectedListRep = row
},
// 代替政策分页
pageChangeReplace (page) {
this.replacePage = page
this.replaceLawsNumForm.page = page
this.getReplaceLawsNumRow()
},
pageSizeChangeReplace (pageSize) {
// this.replaceRows = pageSize
this.replaceLawsNumForm.pageSize = pageSize
this.getReplaceLawsNumRow()
},
// 代替政策编号确定
replaceLawsNumModelBt () {
let textArr = []
if (typeof this.value === 'string') {
if (this.value) {
textArr = this.value.split(',')
}
}
if (this.selectedListRep.length === 0) {
return this.$message({
message: '请先选择数据',
type: 'warning'
})
}
if (this.selectedListRep.length + textArr.length > 20) {
return this.$message({
message: '政策最多选择20项',
type: 'warning'
})
}
this.selectedListRep.map((item) => {
let texts = item.lawsNumber
// if (item.standYear != null && item.standYear !== '') {
// texts = item.standSort !== null ? item.standSort + ' ' + item.standNumber + '-' + item.standYear : item.standNumber + '-' + item.standYear
// } else {
// texts = item.standSort !== null ? item.standSort + ' ' + item.standNumber : item.standNumber
// }
textArr.push(texts)
textArr = [...new Set(textArr)]
this.replaceLawsNumModel = false
})
// this.SarLawsInfoEO.replaceLawsNum = textArr.join(',')
this.$emit('input', textArr.join(','))
this.$refs.selections.clearSelection()
},
// 点击查看
handlePreview (item) {
if (this.$hasPermission('A2HDHMEA6W')) {
let routeUrl = this.$router.resolve({
name: 'OtherLawsDetails',
params: {
id: item.id,
pageType: 'FOREIGN_LAWS'
}
})
window.open(routeUrl.href, '_blank')
} else {
this.$message.warning('无权访问')
}
},
getResetLawsNumRow() {
this.replaceLawsNumForm = {
numberName: '', // 政策编号
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
lawsType: 'FOREIGN',
quoteIdList: '',
menuId: ''
// validFlag: '0'
}
this.getReplaceLawsNumRow()
}
}
}
</script>
<style scoped lang="less">
.add-form-item{
/deep/.el-form-item__content{
.el-textarea{
width: calc(~'100% - 90px');
}
}
}
</style>
@@ -0,0 +1,398 @@
<template>
<!-- <div>-->
<el-col :span="span">
<el-form-item
:label="config.attrName"
:label-width="labelWidth"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
:value="value"
:placeholder="placeholder"
:disabled="disabled"
clearable
type="textarea"
resize="none"
:autosize="true"
@input="handleChange"
></el-input>
<el-button
type="primary"
class="common-button-primary"
round
style="position:absolute;top: 10px;right: 0;"
@click="selectLaws"
v-if="(processModel && !disabled) || !processModel"
>{{config.attrField === 'releventStand' ? '选择标准' :'手动查找'}}</el-button>
</el-form-item>
<el-dialog
:title="config.attrName"
:visible.sync="replaceLawsNumModel"
width="875px"
:close-on-click-modal="false"
@close="replaceLawsNumModelCancel"
:append-to-body="true"
>
<div class="search-area">
<div class="left">
<el-form :model="replaceLawsNumForm" :inline="true" class="label-input-form" @keyup.enter.native="getReplaceLawsNumRowFirst">
<el-form-item label="编号/名称" class="search-item">
<el-input
v-model="numberName"
placeholder="根据编号/名称查找"
clearable
:maxlength="100"></el-input>
</el-form-item>
<el-form-item label="标准来源" class="search-item" v-if="dataSource">
<el-select
v-model="replaceLawsNumForm.standType"
placeholder="请选择标准来源">
<el-option value="INLAND" label="国内标准库"></el-option>
<el-option value="FOREIGN" label="国外标准库"></el-option>
</el-select>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
icon="el-icon-search"
type="primary"
class="common-button-primary"
round
@click="getReplaceLawsNumRowFirst">
</el-button>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
class="common-button-default"
icon="el-icon-refresh-left"
round
type="default"
@click="getResetLawsNumRow"></el-button>
</el-form-item>
</el-form>
</div>
</div>
<el-table
ref="selections"
:data="replaceLawsNumRow"
tooltip-effect="dark"
style="width: 100%;overflow-y: auto;overflow-x: hidden;"
border
:height="300"
:header-cell-style="{background: '#e8e8e8', color: '#333333', fontSize: '16px',
fontWeight: 'bold', height: '48px'}"
@selection-change="selectReplaceStandNumRowChange">
<el-table-column
type="selection"
width="55"
align="center">
</el-table-column>
<el-table-column
label="标准编号">
<template slot-scope="scope">
<a v-if="scope.row.standYear" class="table-jump" @click="handlePreview(scope.row)">{{ scope.row.standSort }} {{ scope.row.standCode }}-{{ scope.row.standYear }}</a>
<a v-else class="table-jump" @click="handlePreview(scope.row)">{{ scope.row.standSort }} {{ scope.row.standCode }}</a>
</template>
</el-table-column>
<el-table-column
prop="standName"
label="标准名称">
</el-table-column>
<el-table-column
prop="issueTime"
label="发布日期"
width="130">
<template slot-scope="scope">{{ ['已发布', 'TBD', ''].includes(scope.row.issueTime) ? scope.row.issueTime : $moment(scope.row.issueTime).format('YYYY-MM-DD') }}</template>
</el-table-column>
<el-table-column
prop="standStatusShow"
label="标准状态"
width="130">
</el-table-column>
</el-table>
<loading :loading="replaceLoading">{{$t('m.dataAcquisition')}}</loading>
<!--分页-->
<pagination
style="position: relative;"
:page="replacePage"
:total="replaceTotal"
@pageChange="pageChangeReplace"
@pageSizeChange="pageSizeChangeReplace"></pagination>
<div slot="footer" class="demo-drawer-footer">
<el-button round class="common-button-default" icon="el-icon-close" @click="replaceLawsNumModel = false">取消</el-button>
<el-button type="primary" round class="common-button-primary" icon="el-icon-check" @click="replaceLawsNumModelBt">提交</el-button>
</div>
</el-dialog>
</el-col>
<!-- </div>-->
</template>
<script>
export default {
name: 'CustomInput',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 是否为流程中使用
processModel: {
type: Boolean,
default: false
},
// label宽度
labelWidth: {
type: String,
default: '150px'
},
// 是否支持数据源切换
dataSource: {
type: Boolean,
default: false
}
},
data () {
return {
replaceLawsNumModel: false,
sarBussionessLawsEO: {
replaceLawsNum: ''
},
// 代替标准号
replaceLawsNumForm: {
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
standType: 'ALL',
quoteIdList: '',
validFlag: '0',
menuId: 'nomenu'
},
numberName: '', // 标准编号
replaceLawsNumRow: [], // 代替政策号 数组内容
replaceTotal: 0,
selectedListRep: [],
replaceLoading: true,
replacePage: 1
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
}
},
methods: {
handleChange (event) {
// const value = event.target.value
const value = event
this.$emit('input', value)
},
selectLaws () {
// if (this.standNumFlag === 1) {
// this.$refs.selections.selectAll(false)
// }
// this.sarBussionessLawsEO.replaceLawsNum = ''
this.replaceLawsNumModel = true
this.getReplaceLawsNumRow()
},
// 代替政策号 请求数据
getReplaceLawsNumRowFirst () {
let advanceSearchVOStr = [
{
connect:'',
field:'STAND_CODE',
type:'like',
value: this.numberName
},
{
connect:'OR',
field:'STAND_NAME',
type:'like',
value: this.numberName
},
]
this.replaceLawsNumForm.advanceSearchVOStr = JSON.stringify(advanceSearchVOStr)
if (this.sarBussionessLawsEO.replaceLawsNum !== null && this.sarBussionessLawsEO.replaceLawsNum !== '') {
this.replaceLawsNumForm.quoteIdList = this.quoteIdList1.toString() === '' ? '' : this.quoteIdList1
} else {
this.quoteIdList1 = []
this.replaceLawsNumForm.quoteIdList = ''
}
this.replaceLawsNumForm.page = 1
this.replacePage = 1
this.$http.get('lawss/sarBussRecords/page', this.replaceLawsNumForm, {
_this: this,
loading: 'replaceLoading'
}, res => {
this.replaceLawsNumRow = res.data.list
this.replaceTotal = res.data.count
if (this.selectedListRep.length !== 0) {
this.selectedListRep.map((list) => {
this.replaceLawsNumRow.map((item) => {
if (list.id === item.id) {
item._checked = true
}
})
})
}
}, e => {
})
},
// 代替政策号 请求数据
getReplaceLawsNumRow () {
if (this.sarBussionessLawsEO.replaceLawsNum !== null && this.sarBussionessLawsEO.replaceLawsNum !== '') {
this.replaceLawsNumForm.quoteIdList = this.quoteIdList1.toString() === '' ? '' : this.quoteIdList1
} else {
this.quoteIdList1 = []
this.replaceLawsNumForm.quoteIdList = ''
}
// this.replaceLawsNumForm.standType = this.config.attrField === 'CBBH' ? 'FOREIGN' : 'INLAND'
this.$http.get('lawss/sarBussRecords/page', this.replaceLawsNumForm, {
_this: this,
loading: 'replaceLoading'
}, res => {
this.replaceLawsNumRow = res.data.list
this.replaceTotal = res.data.count
if (this.selectedListRep.length !== 0) {
this.selectedListRep.map((list) => {
this.replaceLawsNumRow.map((item) => {
if (list.id === item.id) {
item._checked = true
}
})
})
}
}, e => {
})
},
// 代替政策编号-取消
replaceLawsNumModelCancel () {
// this.replaceLawsNumModel = false
this.$refs.selections.clearSelection()
},
// 代替政策号 table选择事件
selectReplaceStandNumRowChange (row) {
this.selectedListRep = row
},
// 代替政策分页
pageChangeReplace (page) {
this.replacePage = page
this.replaceLawsNumForm.page = page
this.getReplaceLawsNumRow()
},
pageSizeChangeReplace (pageSize) {
// this.replaceRows = pageSize
this.replaceLawsNumForm.pageSize = pageSize
this.getReplaceLawsNumRow()
},
// 代替政策编号确定
replaceLawsNumModelBt () {
let textArr = []
if (typeof this.value === 'string') {
if (this.value) {
textArr = this.value.split(',')
}
}
if (this.selectedListRep.length === 0) {
return this.$message({
message: '请先选择数据',
type: 'warning'
})
}
if (this.selectedListRep.length + textArr.length > 20) {
return this.$message({
message: '代替标准号最多选择20项',
type: 'warning'
})
}
this.selectedListRep.map((item) => {
let texts = ''
if (item.standYear != null && item.standYear !== '') {
texts = item.standSort !== null ? item.standSort + ' ' + item.standCode + '-' + item.standYear : item.standCode + '-' + item.standYear
} else {
texts = item.standSort !== null ? item.standSort + ' ' + item.standCode : item.standCode
}
textArr.push(texts)
textArr = [...new Set(textArr)]
this.replaceLawsNumModel = false
})
// this.SarLawsInfoEO.replaceLawsNum = textArr.join(',')
this.$emit('input', textArr.join(','))
this.$refs.selections.clearSelection()
},
// 点击查看
handlePreview (item) {
// let standNum = ''
// if (item.standYear){
// standNum = item.standSort + ' ' + item.standCode + '-' + item.standYear
// } else {
// standNum = item.standSort + ' ' + item.standCode
// }
// // 验证标准号在系统中是否存在
// this.$http.get('lawss/sarBussionessStand/queryReplaceStandInfo', {
// standNum: item.standCode
// }, {
// _this: this
// }, res => {
// if (res.data != null) {
// let routeUrl = this.$router.resolve({
// name: 'OtherStandardDetails',
// params: {
// id: res.data.id,
// pageType: 'BUSINESS_STAND'
// }
// })
// window.open(routeUrl.href, '_blank')
// }else{
// this.$message.error('标准号已不存在!')
// }
// })
this.$emit('checkDetail', item)
},
getResetLawsNumRow () {
this.replacePage = 1
this.replaceLawsNumForm = {
standNumber: '', // 标准编号
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
standType: 'INLAND',
quoteIdList: '',
validFlag: '0'
}
this.getReplaceLawsNumRow()
}
}
}
</script>
<style scoped lang="less">
.add-form-item{
/deep/.el-form-item__content{
.el-textarea{
width: calc(~'100% - 90px');
}
}
}
</style>
@@ -0,0 +1,378 @@
<template>
<!-- <div>-->
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
:value="value"
:placeholder="placeholder"
:disabled="disabled"
:maxlength="maxlength"
clearable
type="textarea"
resize="none"
:autosize="true"
@input="handleChange"
></el-input>
<el-button
type="primary"
class="common-button-primary"
round
style="position:absolute;top: 10px;right: 0;"
@click="selectLaws"
v-if="(processModel && !disabled) || !processModel"
>{{config.attrField === 'releventStand' ? '选择标准' :'手动查找'}}</el-button>
</el-form-item>
<el-dialog
:title="config.attrName"
:visible.sync="replaceLawsNumModel"
width="875px"
:close-on-click-modal="false"
@close="replaceLawsNumModelCancel"
:append-to-body="true"
>
<div class="search-area">
<div class="left">
<el-form :modal="replaceLawsNumForm" :inline="true" class="label-input-form" @keyup.enter.native="getReplaceLawsNumRowFirst">
<el-form-item label="标准来源" class="search-item" v-if="dataSource">
<el-select
v-model="replaceLawsNumForm.standType"
placeholder="请选择标准来源"
@change="dataSourceChange">
<el-option value="INLAND" label="国内标准库"></el-option>
<el-option value="FOREIGN" label="国外标准库"></el-option>
</el-select>
</el-form-item>
<el-form-item label="编号/名称" class="search-item">
<el-input
v-model="replaceLawsNumForm.standNumber"
placeholder="根据编号/名称查找"
clearable
:maxlength="100"></el-input>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
icon="el-icon-search"
type="primary"
class="common-button-primary"
round
@click="getReplaceLawsNumRowFirst">
</el-button>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
class="common-button-default"
icon="el-icon-refresh-left"
round
type="default"
@click="getResetLawsNumRow"></el-button>
</el-form-item>
</el-form>
</div>
</div>
<el-table
ref="selections"
:data="replaceLawsNumRow"
tooltip-effect="dark"
style="width: 100%;overflow-y: auto;overflow-x: hidden;"
border
:height="300"
:header-cell-style="{background: '#e8e8e8', color: '#333333', fontSize: '16px',
fontWeight: 'bold', height: '48px'}"
@selection-change="selectReplaceStandNumRowChange">
<el-table-column
type="selection"
width="55"
align="center">
</el-table-column>
<el-table-column
label="标准编号">
<template slot-scope="scope">
<a v-if="scope.row.standYear" class="table-jump" @click="handlePreview(scope.row)">{{ scope.row.standSort }} {{ scope.row.standNumber }}-{{ scope.row.standYear }}</a>
<a v-else class="table-jump" @click="handlePreview(scope.row)">{{ scope.row.standSort }} {{ scope.row.standNumber }}</a>
</template>
</el-table-column>
<el-table-column
prop="standName"
label="标准名称">
</el-table-column>
<el-table-column
prop="issueTime"
label="发布日期"
width="130">
<template slot-scope="scope">{{ scope.row.issueTime ? $moment(scope.row.issueTime).format('YYYY-MM-DD') : '' }}</template>
</el-table-column>
<el-table-column
prop="standStateShow"
label="标准状态"
width="130">
</el-table-column>
</el-table>
<loading :loading="replaceLoading">{{$t('m.dataAcquisition')}}</loading>
<!--分页-->
<pagination
style="position: relative;"
:page="replacePage"
:total="replaceTotal"
@pageChange="pageChangeReplace"
@pageSizeChange="pageSizeChangeReplace"></pagination>
<div slot="footer" class="demo-drawer-footer">
<el-button round class="common-button-default" icon="el-icon-close" @click="replaceLawsNumModel = false">取消</el-button>
<el-button type="primary" round class="common-button-primary" icon="el-icon-check" @click="replaceLawsNumModelBt">提交</el-button>
</div>
</el-dialog>
</el-col>
<!-- </div>-->
</template>
<script>
export default {
name: 'CustomInput',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
maxlength:{
type:Number,
required:true
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 是否为流程中使用
processModel: {
type: Boolean,
default: false
},
// label宽度
labelWidth: {
type: String,
default: '150px'
},
// 是否支持数据源切换
dataSource: {
type: Boolean,
default: true
}
},
data () {
return {
replaceLawsNumModel: false,
sarBussionessLawsEO: {
replaceLawsNum: ''
},
// 代替标准号
replaceLawsNumForm: {
dataSource: '',
standNumber: '', // 标准编号
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
standType: 'INLAND',
quoteIdList: '',
validFlag: '0',
menuId: 'nomenu'
},
replaceLawsNumRow: [], // 代替政策号 数组内容
replaceTotal: 0,
selectedListRep: [],
replaceLoading: true,
replacePage: 1
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
}
},
methods: {
dataSourceChange (val) {
console.log(val)
},
handleChange (event) {
// const value = event.target.value
const value = event
this.$emit('input', value)
if (value.length==1000){
return this.$message({
message: '相关标准不能输入超过1000个字符',
type: 'warning'
});
}
},
selectLaws () {
this.replaceLawsNumModel = true
this.replaceLawsNumForm.standNumber = ''
this.getReplaceLawsNumRow()
},
// 代替政策号 请求数据
getReplaceLawsNumRowFirst () {
if (this.sarBussionessLawsEO.replaceLawsNum !== null && this.sarBussionessLawsEO.replaceLawsNum !== '') {
this.replaceLawsNumForm.quoteIdList = this.quoteIdList1.toString() === '' ? '' : this.quoteIdList1
} else {
this.quoteIdList1 = []
this.replaceLawsNumForm.quoteIdList = ''
}
this.replaceLawsNumForm.page = 1
this.replacePage = 1
this.$http.get('lawss/sarStandardsInfo/getSarStandardsInfoPage', this.replaceLawsNumForm, {
_this: this,
loading: 'replaceLoading'
}, res => {
this.replaceLawsNumRow = res.data.list
this.replaceTotal = res.data.count
if (this.selectedListRep.length !== 0) {
this.selectedListRep.map((list) => {
this.replaceLawsNumRow.map((item) => {
if (list.id === item.id) {
item._checked = true
}
})
})
}
}, e => {
})
},
// 代替政策号 请求数据
getReplaceLawsNumRow () {
if (this.sarBussionessLawsEO.replaceLawsNum !== null && this.sarBussionessLawsEO.replaceLawsNum !== '') {
this.replaceLawsNumForm.quoteIdList = this.quoteIdList1.toString() === '' ? '' : this.quoteIdList1
} else {
this.quoteIdList1 = []
this.replaceLawsNumForm.quoteIdList = ''
}
this.replaceLawsNumForm.standType = this.config.attrField === 'CBBH' ? 'FOREIGN' : 'INLAND'
this.$http.get('lawss/sarStandardsInfo/getSarStandardsInfoPage', this.replaceLawsNumForm, {
_this: this,
loading: 'replaceLoading'
}, res => {
this.replaceLawsNumRow = res.data.list
this.replaceTotal = res.data.count
if (this.selectedListRep.length !== 0) {
this.selectedListRep.map((list) => {
this.replaceLawsNumRow.map((item) => {
if (list.id === item.id) {
item._checked = true
}
})
})
}
}, e => {
})
},
// 代替政策编号-取消
replaceLawsNumModelCancel () {
// this.replaceLawsNumModel = false
this.$refs.selections.clearSelection()
},
// 代替政策号 table选择事件
selectReplaceStandNumRowChange (row) {
this.selectedListRep = row
},
// 代替政策分页
pageChangeReplace (page) {
this.replacePage = page
this.replaceLawsNumForm.page = page
this.getReplaceLawsNumRow()
},
pageSizeChangeReplace (pageSize) {
// this.replaceRows = pageSize
this.replaceLawsNumForm.pageSize = pageSize
this.getReplaceLawsNumRow()
},
// 代替政策编号确定
replaceLawsNumModelBt () {
let textArr = []
if (typeof this.value === 'string') {
if (this.value) {
textArr = this.value.split(',')
}
}
if (this.selectedListRep.length === 0) {
return this.$message({
message: '请先选择数据',
type: 'warning'
})
}
if (this.selectedListRep.length + textArr.length > 20) {
return this.$message({
message: '标准最多选择20项',
type: 'warning'
})
}
this.selectedListRep.map((item) => {
let texts = ''
if (item.standYear != null && item.standYear !== '') {
texts = item.standSort !== null ? item.standSort + ' ' + item.standNumber + '-' + item.standYear : item.standNumber + '-' + item.standYear
} else {
texts = item.standSort !== null ? item.standSort + ' ' + item.standNumber : item.standNumber
}
textArr.push(texts)
textArr = [...new Set(textArr)]
this.replaceLawsNumModel = false
})
// this.SarLawsInfoEO.replaceLawsNum = textArr.join(',')
this.$emit('input', textArr.join(','))
this.$refs.selections.clearSelection()
},
// 点击查看
handlePreview (item) {
let routeUrl = this.$router.resolve({
name: 'OtherStandardDetails',
params: {
id: item.id,
pageType: 'INLAND_STAND'
}
})
window.open(routeUrl.href, '_blank')
},
getResetLawsNumRow () {
this.replaceLawsNumForm = {
standNumber: '', // 标准编号
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
standType: 'INLAND',
quoteIdList: '',
validFlag: '0'
}
this.getReplaceLawsNumRow()
}
}
}
</script>
<style scoped lang="less">
.add-form-item{
/deep/.el-form-item__content{
.el-textarea{
width: calc(~'100% - 90px');
}
}
}
</style>
@@ -0,0 +1,379 @@
<template>
<!-- <div>-->
<el-col :span="span">
<el-form-item
:label="config.attrName"
:label-width="labelWidth"
class="add-form-item"
:prop="config.attrField"
:class="{'form-item-disabled': disabled}"
>
<el-input
:value="value"
:placeholder="placeholder"
:disabled="disabled"
clearable
type="textarea"
resize="none"
:autosize="true"
@input="handleChange"
></el-input>
<el-button
type="primary"
class="common-button-primary"
round
style="position:absolute;top: 10px;right: 0;"
@click="selectLaws"
v-if="(processModel && !disabled) || !processModel"
>{{config.attrField === 'releventStand' ? '选择标准' :'手动查找'}}</el-button>
</el-form-item>
<el-dialog
:title="config.attrName"
:visible.sync="replaceLawsNumModel"
width="875px"
:close-on-click-modal="false"
@close="replaceLawsNumModelCancel"
:append-to-body="true"
>
<div class="search-area">
<div class="left">
<el-form :modal="replaceLawsNumForm" :inline="true" class="label-input-form" @keyup.enter.native="getReplaceLawsNumRowFirst">
<el-form-item label="编号/名称" class="search-item">
<el-input
v-model="replaceLawsNumForm.standNumber"
placeholder="根据编号/名称查找"
clearable
:maxlength="100"></el-input>
</el-form-item>
<el-form-item label="标准来源" class="search-item" v-if="dataSource">
<el-select
v-model="replaceLawsNumForm.standType"
placeholder="请选择标准来源">
<el-option value="INLAND" label="国内标准库"></el-option>
<el-option value="FOREIGN" label="国外标准库"></el-option>
</el-select>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
icon="el-icon-search"
type="primary"
class="common-button-primary"
round
@click="getReplaceLawsNumRowFirst">
</el-button>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
class="common-button-default"
icon="el-icon-refresh-left"
round
type="default"
@click="getResetLawsNumRow"></el-button>
</el-form-item>
</el-form>
</div>
</div>
<el-table
ref="selections"
:data="replaceLawsNumRow"
tooltip-effect="dark"
style="width: 100%;overflow-y: auto;overflow-x: hidden;"
border
:height="300"
:header-cell-style="{background: '#e8e8e8', color: '#333333', fontSize: '16px',
fontWeight: 'bold', height: '48px'}"
@selection-change="selectReplaceStandNumRowChange">
<el-table-column
type="selection"
width="55"
align="center">
</el-table-column>
<el-table-column
label="标准编号">
<template slot-scope="scope">
<a v-if="scope.row.standYear" class="table-jump" @click="handlePreview(scope.row)">{{ scope.row.standSortShow }} {{ scope.row.standNumber }}-{{ scope.row.standYear }}</a>
<a v-else class="table-jump" @click="handlePreview(scope.row)">{{ scope.row.standSortShow }} {{ scope.row.standNumber }}</a>
</template>
</el-table-column>
<el-table-column
prop="standName"
label="标准名称">
</el-table-column>
<el-table-column
prop="issueTime"
label="发布日期"
width="130">
<template slot-scope="scope">{{ ['已发布', 'TBD', ''].includes(scope.row.issueTime) ? scope.row.issueTime : $moment(scope.row.issueTime).format('YYYY-MM-DD') }}</template>
</el-table-column>
<el-table-column
prop="standStateShow"
label="标准状态"
width="130">
</el-table-column>
</el-table>
<loading :loading="replaceLoading">{{$t('m.dataAcquisition')}}</loading>
<!--分页-->
<pagination
style="position: relative;"
:page="replacePage"
:total="replaceTotal"
@pageChange="pageChangeReplace"
@pageSizeChange="pageSizeChangeReplace"></pagination>
<div slot="footer" class="demo-drawer-footer">
<el-button round class="common-button-default" icon="el-icon-close" @click="replaceLawsNumModel = false">取消</el-button>
<el-button type="primary" round class="common-button-primary" icon="el-icon-check" @click="replaceLawsNumModelBt">提交</el-button>
</div>
</el-dialog>
</el-col>
<!-- </div>-->
</template>
<script>
export default {
name: 'CustomInput',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 是否为流程中使用
processModel: {
type: Boolean,
default: false
},
// label宽度
labelWidth: {
type: String,
default: '150px'
},
// 是否支持数据源切换
dataSource: {
type: Boolean,
default: false
}
},
data () {
return {
replaceLawsNumModel: false,
sarBussionessLawsEO: {
replaceLawsNum: ''
},
// 代替标准号
replaceLawsNumForm: {
standNumber: '', // 标准编号
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
standType: 'ALL',
quoteIdList: '',
validFlag: '0',
menuId: 'nomenu'
},
replaceLawsNumRow: [], // 代替政策号 数组内容
replaceTotal: 0,
selectedListRep: [],
replaceLoading: true,
replacePage: 1
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
}
},
methods: {
handleChange (event) {
// const value = event.target.value
const value = event
this.$emit('input', value)
},
selectLaws () {
// if (this.standNumFlag === 1) {
// this.$refs.selections.selectAll(false)
// }
// this.sarBussionessLawsEO.replaceLawsNum = ''
this.replaceLawsNumModel = true
this.getReplaceLawsNumRow()
},
// 代替政策号 请求数据
getReplaceLawsNumRowFirst () {
if (this.sarBussionessLawsEO.replaceLawsNum !== null && this.sarBussionessLawsEO.replaceLawsNum !== '') {
this.replaceLawsNumForm.quoteIdList = this.quoteIdList1.toString() === '' ? '' : this.quoteIdList1
} else {
this.quoteIdList1 = []
this.replaceLawsNumForm.quoteIdList = ''
}
this.replaceLawsNumForm.page = 1
this.replacePage = 1
this.$http.get('lawss/sarStandardsInfo/getSarStandardsInfoPage', this.replaceLawsNumForm, {
_this: this,
loading: 'replaceLoading'
}, res => {
this.replaceLawsNumRow = res.data.list
this.replaceTotal = res.data.count
if (this.selectedListRep.length !== 0) {
this.selectedListRep.map((list) => {
this.replaceLawsNumRow.map((item) => {
if (list.id === item.id) {
item._checked = true
}
})
})
}
}, e => {
})
},
// 代替政策号 请求数据
getReplaceLawsNumRow () {
if (this.sarBussionessLawsEO.replaceLawsNum !== null && this.sarBussionessLawsEO.replaceLawsNum !== '') {
this.replaceLawsNumForm.quoteIdList = this.quoteIdList1.toString() === '' ? '' : this.quoteIdList1
} else {
this.quoteIdList1 = []
this.replaceLawsNumForm.quoteIdList = ''
}
// this.replaceLawsNumForm.standType = this.config.attrField === 'CBBH' ? 'FOREIGN' : 'INLAND'
this.$http.get('lawss/sarStandardsInfo/getSarStandardsInfoPage', this.replaceLawsNumForm, {
_this: this,
loading: 'replaceLoading'
}, res => {
this.replaceLawsNumRow = res.data.list
this.replaceTotal = res.data.count
if (this.selectedListRep.length !== 0) {
this.selectedListRep.map((list) => {
this.replaceLawsNumRow.map((item) => {
if (list.id === item.id) {
item._checked = true
}
})
})
}
}, e => {
})
},
// 代替政策编号-取消
replaceLawsNumModelCancel () {
// this.replaceLawsNumModel = false
this.$refs.selections.clearSelection()
},
// 代替政策号 table选择事件
selectReplaceStandNumRowChange (row) {
this.selectedListRep = row
},
// 代替政策分页
pageChangeReplace (page) {
this.replacePage = page
this.replaceLawsNumForm.page = page
this.getReplaceLawsNumRow()
},
pageSizeChangeReplace (pageSize) {
// this.replaceRows = pageSize
this.replaceLawsNumForm.pageSize = pageSize
this.getReplaceLawsNumRow()
},
// 代替政策编号确定
replaceLawsNumModelBt () {
let textArr = []
if (typeof this.value === 'string') {
if (this.value) {
textArr = this.value.split(',')
}
}
if (this.selectedListRep.length === 0) {
return this.$message({
message: '请先选择数据',
type: 'warning'
})
}
if (this.selectedListRep.length + textArr.length > 20) {
return this.$message({
message: `${this.config.attrName}最多选择20项`,
type: 'warning'
})
}
this.selectedListRep.map((item) => {
let texts = ''
if (item.standYear != null && item.standYear !== '') {
texts = item.standSortShow !== null ? item.standSortShow + ' ' + item.standNumber + '-' + item.standYear : item.standNumber + '-' + item.standYear
} else {
texts = item.standSortShow !== null ? item.standSortShow + ' ' + item.standNumber : item.standNumber
}
textArr.push(texts)
textArr = [...new Set(textArr)]
this.replaceLawsNumModel = false
})
// this.SarLawsInfoEO.replaceLawsNum = textArr.join(',')
this.$emit('input', textArr.join(','))
this.$refs.selections.clearSelection()
},
// 点击查看
handlePreview (item) {
let standNum = ''
if (item.standYear){
standNum = item.standSort + ' ' + item.standNumber + '-' + item.standYear
} else {
standNum = item.standSort + ' ' + item.standNumber
}
// 验证标准号在系统中是否存在
this.$http.post('lawss/sarTestItem/validateStandNumber', {
standnumber: standNum
}, {
_this: this
}, res => {
let routeUrl = this.$router.resolve({
name: 'OtherStandardDetails',
params: {
id: item.id,
pageType: 'INLAND_STAND'
}
})
window.open(routeUrl.href, '_blank')
})
},
getResetLawsNumRow () {
this.replacePage = 1
this.replaceLawsNumForm = {
standNumber: '', // 标准编号
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
standType: 'INLAND',
quoteIdList: '',
validFlag: '0'
}
this.getReplaceLawsNumRow()
}
}
}
</script>
<style scoped lang="less">
.add-form-item{
/deep/.el-form-item__content{
.el-textarea{
width: calc(~'100% - 90px');
}
}
}
</style>
@@ -0,0 +1,398 @@
<template>
<!-- <div>-->
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item leftButton"
:class="{'form-item-disabled': disabled}"
>
<el-input
:value="value"
:placeholder="placeholder"
:disabled="disabled"
clearable
@input="handleChange"
></el-input>
<el-button
type="primary"
class="common-button-primary"
round
style="position:absolute;top: 10px;right: 0;"
@click="selectLaws"
v-if="(processModel && !disabled) || !processModel"
>手动查找</el-button>
</el-form-item>
<el-dialog
:title="config.attrName"
:visible.sync="replaceLawsNumModel"
width="875px"
:close-on-click-modal="false"
@close="replaceLawsNumModelCancel"
:append-to-body="true"
>
<div class="search-area">
<div class="left">
<el-form :modal="replaceLawsNumForm" :inline="true" class="label-input-form" @keyup.enter.native="getReplaceLawsNumRowSearch">
<el-form-item label="数据来源" class="search-item">
<el-select v-model="replaceLawsNumForm.dataSource" filterable>
<el-option
v-for="item in dataSourceOptions"
:key="item.value"
:value="item.value"
:label="item.label"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="企标编号/标准名称" class="search-item input-width">
<el-input
v-model="replaceLawsNumForm.numberName"
placeholder="根据企标编号/标准名称查找"
clearable
:maxlength="100"></el-input>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
icon="el-icon-search"
type="primary"
class="common-button-primary"
round
@click="getReplaceLawsNumRowSearch">
</el-button>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
class="common-button-default"
icon="el-icon-refresh-left"
round
type="default"
@click="getResetLawsNumRow"></el-button>
</el-form-item>
</el-form>
</div>
</div>
<el-table
ref="selections"
:data="replaceLawsNumRow"
tooltip-effect="dark"
style="width: 100%;overflow-y: auto;overflow-x: hidden;"
border
:height="300"
:header-cell-style="{background: '#e8e8e8', color: '#333333', fontSize: '16px',
fontWeight: 'bold', height: '48px'}"
@selection-change="selectReplaceStandNumRowChange">
<el-table-column
type="selection"
width="55"
align="center">
</el-table-column>
<!-- <el-table-column-->
<!-- prop="standSortShow"-->
<!-- label="企标类别"-->
<!-- min-width="130"-->
<!-- >-->
<!-- </el-table-column>-->
<el-table-column
label="企标编号"
min-width="130">
<template slot-scope="scope">
<span v-if="dataSource === 'BUSINESS'">
<a v-if="scope.row.standYear" class="table-jump" @click="handlePreview(scope.row)">{{ scope.row.standCode }}-{{ scope.row.standYear }}</a>
<a v-else class="table-jump" @click="handlePreview(scope.row)">{{ scope.row.standCode }}</a>
</span>
<span v-else>
<a v-if="scope.row.standYear" class="table-jump" @click="handlePreview(scope.row)">{{ scope.row.standSortShow }} {{ scope.row.standNumber }}-{{ scope.row.standYear }}</a>
<a v-else @click="handlePreview(scope.row)" class="table-jump">{{ scope.row.standSortShow }} {{ scope.row.standNumber }}</a>
</span>
</template>
</el-table-column>
<el-table-column
prop="standName"
label="标准名称"
min-width="130">
</el-table-column>
<el-table-column
prop="issueTime"
label="发布日期"
width="130">
</el-table-column>
<el-table-column
prop="putTime"
label="实施日期"
width="130">
</el-table-column>
<el-table-column
prop="standStateShow"
label="标准状态"
width="130">
</el-table-column>
</el-table>
<loading :loading="replaceLoading">{{$t('m.dataAcquisition')}}</loading>
<!--分页-->
<pagination
style="position: relative;"
:page="replacePage"
:total="replaceTotal"
@pageChange="pageChangeReplace"
@pageSizeChange="pageSizeChangeReplace"></pagination>
<div slot="footer" class="demo-drawer-footer">
<el-button round class="common-button-default" icon="el-icon-close" @click="replaceLawsNumModel = false">取消</el-button>
<el-button type="primary" round class="common-button-primary" icon="el-icon-check" @click="replaceLawsNumModelBt">提交</el-button>
</div>
</el-dialog>
</el-col>
<!-- </div>-->
</template>
<script>
export default {
name: 'CustomInput',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 是否为流程中使用
processModel: {
type: Boolean,
default: false
},
// label宽度
labelWidth: {
type: String,
default: '150px'
}
},
data () {
return {
replaceLawsNumModel: false,
sarBussionessLawsEO: {
replaceLawsNum: ''
},
// 代替标准号
replaceLawsNumForm: {
dataSource: 'BUSINESS', // 数据来源
numberName: '', // 政策编号
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
quoteIdList: '',
menuId: '',
validFlag: 0
},
replaceLawsNumRow: [], // 代替政策号 数组内容
replaceTotal: 0,
selectedListRep: [],
replaceLoading: true,
replacePage: 1,
// 数据搜索 数据来源list
dataSourceOptions: [
{value: 'INLAND_STAND', label: '国内标准法规'},
{value: 'FOREIGN_STAND', label: '海外标准法规'},
{value: 'BUSINESS', label: '企业标准 '}
],
dataSource: 'BUSINESS'
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
}
},
methods: {
getReplaceLawsNumRowSearch () {
this.replaceLawsNumForm.page = 1
this.replacePage = 1
this.getReplaceLawsNumRow()
},
handleChange (event) {
// const value = event.target.value
const value = event
this.$emit('input', value)
},
selectLaws () {
// if (this.standNumFlag === 1) {
// this.$refs.selections.selectAll(false)
// }
// this.sarBussionessLawsEO.replaceLawsNum = ''
this.replaceLawsNumModel = true
this.getReplaceLawsNumRow()
},
// 代替政策号 请求数据
getReplaceLawsNumRow () {
if (this.sarBussionessLawsEO.replaceLawsNum !== null && this.sarBussionessLawsEO.replaceLawsNum !== '') {
this.replaceLawsNumForm.quoteIdList = this.quoteIdList1.toString() === '' ? '' : this.quoteIdList1
} else {
this.quoteIdList1 = []
this.replaceLawsNumForm.quoteIdList = ''
}
const formData = {
...this.replaceLawsNumForm
}
this.dataSource = this.replaceLawsNumForm.dataSource
// 根据数据来源,查询不同的标准库
formData.standType = this.replaceLawsNumForm.dataSource === 'INLAND_STAND' ? 'INLAND'
: this.replaceLawsNumForm.dataSource === 'FOREIGN_STAND' ? 'FOREIGN' : ''
formData.standNumber = formData.numberName
let url = this.replaceLawsNumForm.dataSource === 'BUSINESS' ? 'lawss/sarBussionessStand/getSarBussionStandPage' : 'lawss/sarStandardsInfo/getSarStandardsInfoPage'
this.$http.get(url, formData, {
_this: this,
loading: 'replaceLoading'
}, res => {
this.replaceLawsNumRow = res.data.list
this.replaceTotal = res.data.count
if (this.selectedListRep.length !== 0) {
this.selectedListRep.map((list) => {
this.replaceLawsNumRow.map((item) => {
if (list.id === item.id) {
item._checked = true
}
})
})
}
}, e => {
})
},
// 代替政策编号-取消
replaceLawsNumModelCancel () {
// this.replaceLawsNumModel = false
this.$refs.selections.clearSelection()
},
// 代替政策号 table选择事件
selectReplaceStandNumRowChange (row) {
this.selectedListRep = row
},
// 代替政策分页
pageChangeReplace (page) {
this.replacePage = page
this.replaceLawsNumForm.page = page
this.getReplaceLawsNumRow()
},
pageSizeChangeReplace (pageSize) {
// this.replaceRows = pageSize
this.replaceLawsNumForm.pageSize = pageSize
this.getReplaceLawsNumRow()
},
// 代替政策编号确定
replaceLawsNumModelBt () {
let textArr = []
if (typeof this.value === 'string') {
if (this.value) {
textArr = this.value.split(',')
}
}
if (this.selectedListRep.length === 0) {
return this.$message({
message: '请先选择数据',
type: 'warning'
})
}
if (this.selectedListRep.length + textArr.length > 20) {
return this.$message({
message: '代替标准号最多选择20项',
type: 'warning'
})
}
this.selectedListRep.map((item) => {
let texts = ''
// 判断数据是国内外法规标准还是企业标准
if (this.dataSource === 'BUSINESS') {
if (item.standYear != null && item.standYear !== '') {
texts = item.standCode + '-' + item.standYear
} else {
texts = item.standCode
}
} else {
if (item.standYear != null && item.standYear !== '') {
texts = item.standSortShow + ' ' + item.standNumber + '-' + item.standYear
} else {
texts = item.standSortShow + ' ' + item.standNumber
}
}
textArr.push(texts)
textArr = [...new Set(textArr)]
this.replaceLawsNumModel = false
})
// this.SarLawsInfoEO.replaceLawsNum = textArr.join(',')
this.$emit('input', textArr.join(','))
this.$refs.selections.clearSelection()
},
// 点击查看
handlePreview (item) {
let name = ''
let pageType = ''
switch (this.dataSource) {
case 'INLAND_STAND':
name = 'OtherStandardDetails'
pageType = 'INLAND_STAND'
break
case 'FOREIGN_STAND':
name = 'OtherStandardDetails'
pageType = 'FOREIGN_STAND'
break
case 'BUSINESS':
name = 'OtherBussStandardDetails'
pageType = 'BUSINESS_STAND'
break
}
let routeUrl = this.$router.resolve({
name: name,
params: {
id: item.id,
pageType: pageType
}
})
window.open(routeUrl.href, '_blank')
},
getResetLawsNumRow () {
this.replaceLawsNumForm = {
dataSource: 'BUSINESS',
numberName: '', // 政策编号
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
lawsType: 'FOREIGN',
quoteIdList: '',
validFlag: '0'
}
this.getReplaceLawsNumRow()
}
}
}
</script>
<style scoped lang="less">
/deep/.el-dialog__body {
padding: 0 20px 0;
}
/deep/.el-dialog__footer {
padding: 0 20px 20px;
}
/deep/.input-width input.el-input__inner {
width: 220px;
}
</style>
@@ -0,0 +1,348 @@
<template>
<!-- <div>-->
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
:value="value"
:placeholder="placeholder"
:disabled="disabled"
clearable
@input="handleChange"
></el-input>
<el-button
type="primary"
class="common-button-primary"
round
style="position:absolute;top: 10px;right: 0;"
@click="selectLaws"
v-if="(processModel && !disabled) || !processModel"
>手动查找</el-button>
</el-form-item>
<el-dialog
:title="config.attrName"
:visible.sync="replaceLawsNumModel"
width="875px"
:close-on-click-modal="false"
@close="replaceLawsNumModelCancel"
:append-to-body="true"
>
<div class="search-area">
<div class="left">
<el-form :modal="replaceLawsNumForm" :inline="true" class="label-input-form" @keyup.enter.native="getReplaceLawsNumRow">
<el-form-item label="编号/名称" class="search-item">
<el-input v-model="replaceLawsNumForm.standNumber" placeholder="根据编号/名称查找" clearable :maxlength="100"></el-input>
</el-form-item>
<el-form-item label="标准来源" class="search-item" v-if="dataSource">
<el-select
v-model="replaceLawsNumForm.standType"
placeholder="请选择标准来源">
<el-option value="ALL" label="全部"></el-option>
<el-option value="INLAND" label="国内标准库"></el-option>
<el-option value="FOREIGN" label="国外标准库"></el-option>
</el-select>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
icon="el-icon-search"
type="primary"
class="common-button-primary"
round
@click="getReplaceLawsNumRow">
</el-button>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
class="common-button-default"
icon="el-icon-refresh-left"
round
type="default"
@click="getResetLawsNumRow"></el-button>
</el-form-item>
</el-form>
</div>
</div>
<el-table
ref="selections"
:data="replaceLawsNumRow"
tooltip-effect="dark"
style="width: 100%;overflow-y: auto;overflow-x: hidden;"
border
:height="300"
:header-cell-style="{background: '#e8e8e8', color: '#333333', fontSize: '16px',
fontWeight: 'bold', height: '48px'}"
@selection-change="selectReplaceStandNumRowChange">
<el-table-column
type="selection"
width="55"
align="center">
</el-table-column>
<el-table-column
label="标准编号"
width="130">
<template slot-scope="scope">
<a v-if="scope.row.standYear" class="table-jump" @click="handlePreview(scope.row)">{{ scope.row.standSort }} {{ scope.row.standNumber }}-{{ scope.row.standYear }}</a>
<a v-else class="table-jump" @click="handlePreview(scope.row)">{{ scope.row.standSort }} {{ scope.row.standNumber }}</a>
</template>
</el-table-column>
<el-table-column
prop="standName"
label="标准名称"
width="130">
</el-table-column>
<el-table-column
prop="issueTime"
label="发布日期"
width="130">
<template slot-scope="scope">{{ scope.row.issueTime || '' }}</template>
</el-table-column>
<el-table-column
prop="putTime"
label="实施日期"
width="130">
</el-table-column>
<el-table-column
prop="standNatureShow"
label="标准性质"
width="130">
</el-table-column>
<el-table-column
prop="standStateShow"
label="标准状态"
width="130">
</el-table-column>
</el-table>
<loading :loading="replaceLoading">{{$t('m.dataAcquisition')}}</loading>
<!--分页-->
<pagination
style="position: relative;"
:page="replacePage"
:total="replaceTotal"
@pageChange="pageChangeReplace"
@pageSizeChange="pageSizeChangeReplace"></pagination>
<div slot="footer" class="demo-drawer-footer">
<el-button round class="common-button-default" icon="el-icon-close" @click="replaceLawsNumModel = false">取消</el-button>
<el-button type="primary" round class="common-button-primary" icon="el-icon-check" @click="replaceLawsNumModelBt">提交</el-button>
</div>
</el-dialog>
</el-col>
<!-- </div>-->
</template>
<script>
export default {
name: 'CustomInput',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 是否为流程中使用
processModel: {
type: Boolean,
default: false
},
// label宽度
labelWidth: {
type: String,
default: '150px'
},
// 数据来源
dataSourceFrom: {
type: String
},
// 是否可区分数据来源
dataSource: {
type: Boolean,
default: false
}
},
data() {
return {
replaceLawsNumModel: false,
sarBussionessLawsEO: {
replaceLawsNum: ''
},
// 代替标准号
replaceLawsNumForm: {
standNumber: '', // 政策编号
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
standType: 'ALL',
quoteIdList: '',
validFlag: '0',
menuId: 'nomenu'
},
replaceLawsNumRow: [], // 代替政策号 数组内容
replaceTotal: 0,
selectedListRep: [],
replaceLoading: true,
replacePage: 1,
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
}
},
methods: {
handleChange (event) {
// const value = event.target.value
const value = event
this.$emit('input', value)
},
selectLaws () {
// if (this.standNumFlag === 1) {
// this.$refs.selections.selectAll(false)
// }
// this.sarBussionessLawsEO.replaceLawsNum = ''
this.replaceLawsNumModel = true
this.getReplaceLawsNumRow()
},
// 代替政策号 请求数据
getReplaceLawsNumRow () {
if (this.sarBussionessLawsEO.replaceLawsNum !== null && this.sarBussionessLawsEO.replaceLawsNum !== '') {
this.replaceLawsNumForm.quoteIdList = this.quoteIdList1.toString() === '' ? '' : this.quoteIdList1
} else {
this.quoteIdList1 = []
this.replaceLawsNumForm.quoteIdList = ''
}
this.$http.get('lawss/sarStandardsInfo/getSarStandardsInfoPage', this.replaceLawsNumForm, {
_this: this,
loading: 'replaceLoading'
}, res => {
this.replaceLawsNumRow = res.data.list
this.replaceTotal = res.data.count
if (this.selectedListRep.length !== 0) {
this.selectedListRep.map((list) => {
this.replaceLawsNumRow.map((item) => {
if (list.id === item.id) {
item._checked = true
}
})
})
}
}, e => {
})
},
// 代替政策编号-取消
replaceLawsNumModelCancel () {
// this.replaceLawsNumModel = false
this.$refs.selections.clearSelection()
},
// 代替政策号 table选择事件
selectReplaceStandNumRowChange (row) {
this.selectedListRep = row
},
// 代替政策分页
pageChangeReplace (page) {
this.replacePage = page
this.replaceLawsNumForm.page = page
this.getReplaceLawsNumRow()
},
pageSizeChangeReplace (pageSize) {
// this.replaceRows = pageSize
this.replaceLawsNumForm.pageSize = pageSize
this.getReplaceLawsNumRow()
},
// 代替政策编号确定
replaceLawsNumModelBt () {
let textArr = []
if (typeof this.value === 'string') {
if (this.value) {
textArr = this.value.split(',')
}
}
if (this.selectedListRep.length === 0) {
return this.$message({
message: '请先选择数据',
type: 'warning'
})
}
if (this.selectedListRep.length + textArr.length > 20) {
return this.$message({
message: '代替标准号最多选择20项',
type: 'warning'
})
}
this.selectedListRep.map((item) => {
let texts = ''
if (item.standYear != null && item.standYear !== '') {
texts = item.standSort !== null ? item.standSort + ' ' + item.standNumber + '-' + item.standYear : item.standNumber + '-' + item.standYear
} else {
texts = item.standSort !== null ? item.standSort + ' ' + item.standNumber : item.standNumber
}
textArr.push(texts)
textArr = [...new Set(textArr)]
this.replaceLawsNumModel = false
})
// this.SarLawsInfoEO.replaceLawsNum = textArr.join(',')
this.$emit('input', textArr.join(','))
this.$refs.selections.clearSelection()
},
// 点击查看
handlePreview (item) {
let routeUrl = this.$router.resolve({
name: 'OtherBussStandardDetails',
params: {
id: item.id,
pageType: 'BUSINESS_STAND'
}
})
window.open(routeUrl.href, '_blank')
},
getResetLawsNumRow() {
this.replacePage = 1
this.replaceLawsNumForm = {
standNumber: '', // 政策编号
page: 1,
pageSize: this.$store.getters.userInfo.configContent,
total: 0,
standType: 'FOREIGN',
quoteIdList: '',
validFlag: '0'
}
this.getReplaceLawsNumRow()
}
},
watch: {
dataSourceFrom: {
handler (val) {
this.replaceLawsNumForm.standType = val
}
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,70 @@
<!-- 数字输入框 -->
<template>
<!-- <div>-->
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
label-width="150px"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
:value="value"
:placeholder="placeholder"
:disabled="disabled"
clearable
@input="handleChange"
></el-input>
</el-form-item>
</el-col>
<!-- </div>-->
</template>
<script>
export default {
name: 'CustomInputNumber',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
}
},
methods: {
handleChange (event) {
// const value = event.target.value
let value = event
value = value.replace(/^\D*([0-9]\d*\.?\d{0,2})?.*$/,'$1')
this.$emit('input', value)
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,405 @@
<template>
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item expand-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
v-model="checkedName"
:placeholder="'请选择' + config.attrName"
readonly
:disabled="disabled"
:id="config.attrField"
@click.native="handleClick"
/>
</el-form-item>
<el-drawer
:title="config.attrName"
:visible.sync="visible"
:wrapper-closable="false"
size="350px"
append-to-body
class="org-tree"
@opened="drawerOpen"
@close="handleTreeDrawerCancel"
>
<div :class="{'demo-drawer-content': config.attrType === 'SEL_OPTS'}">
<template v-if="!isFO">
<dept-tree
:key="config.attrField"
:ref="config.attrField"
:all-dept="config.selVal !== 'ORGLIST'"
expandAll
:show-user="config.selVal === 'USERLIST' || config.selVal === 'ROLELIST'"
:check-enable="config.attrType === 'SEL_OPTS'"
:deptSelect="config.selVal === 'ORGLIST'"
:treeDivId="config.attrField + 'Tree'"
:editable="false"
:onlyChecked="config.attrType === 'SEL_OPTS'"
:chkboxType="{ 'Y': '', 'N': '' }"
@treeOnCheck="handleTreeOnCheck"
@treeDblClick="handleTreeDblClick">
</dept-tree>
</template>
<template v-else>
<laws-tree
v-if="visible"
:key="config.attrField"
:ref="config.attrField"
:zNodes="zNodesRole"
expandAll
:check-enable="config.attrType === 'SEL_OPTS' || checkEnable"
:deptSelect="config.selVal === 'ORGLIST'"
:treeDivId="config.attrField + 'Tree'"
:editable="false"
:onlyChecked="config.attrType === 'SEL_OPTS'"
:chkboxType="{ 'Y': '', 'N': '' }"
:initNotCheck="initNotCheck"
@treeOnCheck="handleTreeOnCheck"
@treeDblClick="handleTreeDblClick"></laws-tree>
</template>
</div>
<div class="demo-drawer-footer" v-if="config.attrType === 'SEL_OPTS' || checkEnable">
<el-button
round
class="common-button-primary"
icon="el-icon-check"
type="primary"
@click="handleTreeDrawerConfirm">确定
</el-button>
<el-button
round
class="common-button-default"
icon="el-icon-close"
@click="handleTreeDrawerCancel">取消</el-button>
</div>
</el-drawer>
</el-col>
</template>
<script>
import eventHub from '@/common/eventHub'
export default {
name: 'OrgTree',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 是否显示全部部门
allDept: {
type: Boolean,
default: true
},
zNodes: {
type: Array,
default: () => {
return []
}
},
// 原数据对象
dataModel: {
type: Object,
default: () => {
return {}
}
},
labelWidth: {
type: String,
default: '150px'
},
// 是否为多选
checkEnable: {
type: Boolean,
default: false
},
// 加载时不执行默认选中
initNotCheck: {
type: Boolean,
default: true
}
},
data () {
return {
visible: false,
treeCheckNode: [],
checkedName: '',
zNodesRole: [],
roleList: [],
loading: false
}
},
computed: {
placeholder () {
return `请选择${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
isString (str) {
return (typeof str === 'string') && str.constructor === String
},
isFO () {
return this.config.attrField === 'FO'
},
ZRBM () {
return this.dataModel['ZRBM'] || ''
}
},
methods: {
handleTreeDblClick (treeId, treeNode) {
this.checkedName = treeNode.userName || treeNode.oldname || treeNode.name
this.$emit('input', treeNode.id)
this.$emit('on-checked', this.checkedName)
this.$emit('on-dept', treeNode.pOrgId, treeNode.pOrgName)
this.visible = false
},
handleTreeOnCheck (treeCheckNode) {
this.treeCheckNode = treeCheckNode
},
getShowName (id) {
let name = ''
this.zNodes.map(item => {
if (item.id === id) {
name = item.oldname || item.name
}
})
return name
},
handleTreeDrawerConfirm () {
if (this.config.selVal === 'USERLIST' || this.config.selVal === 'ROLELIST') {
let checkedList = []
let checkedNameList = []
let deptIdList = []
let deptNameList = []
this.treeCheckNode.map(item => {
if (!item.isParent) {
checkedList.push(item.id)
checkedNameList.push(item.userName || item.oldname || item.name)
deptIdList.push(item.pOrgId)
deptNameList.push(item.pOrgName)
}
})
this.checkedName = checkedNameList.join(',')
this.$emit('input', checkedList.join(','))
this.$emit('on-checked', this.checkedName)
this.$emit('on-dept', [...new Set(deptIdList)].join(','), [...new Set(deptNameList)].join(','))
} else {
const checkedList = []
const checkedNameList = []
this.treeCheckNode.map(item => {
checkedList.push(item.id)
if (item.oldname) {
checkedNameList.push(item.oldname)
} else {
checkedNameList.push(item.name)
}
})
this.checkedName = checkedNameList.join(',')
this.$emit('input', checkedList.join(','))
this.$emit('on-checked', this.checkedName)
}
this.visible = false
},
handleTreeDrawerCancel () {
this.visible = false
this.zNodesRole = []
},
// 赋值回显人员和部门
drawerOpen () {
let checkedArr = this.value ? this.value.split(',') : []
if (checkedArr.length > 0) {
setTimeout(() => {
this.$nextTick(() => {
this.$refs[this.config.attrField].checkedNode(checkedArr)
})
}, 500)
}
},
handleClick () {
if (this.disabled) {
return false
}
if (this.isFO) {
if (!this.dataModel.ZRBM || this.dataModel.ZRBM === '') {
this.$message.warning('请先选择责任部门')
} else {
this.visible = true
this.getUserByRole(this.dataModel.ZRBM)
}
} else {
this.visible = true
}
},
// 获取角色列表
selectRoleList () {
this.$http.get('sys/role/findAll', {}, {_this: this}, res => {
let roleList = res.data
let roleOpList = []
for (let index = 0; index < roleList.length; index++) {
let role = roleList[index]
let roleOption = {}
roleOption.label = role.name
roleOption.value = role.id
roleOpList.push(roleOption)
}
this.roleList = roleOpList
}, e => {})
},
// 根据角色名称获取角色id
// queryRoleIdByRoleName (roleName) {
// let roleId = ''
// this.roleList.map(item => {
// if (item.label === roleName) {
// roleId = item.value
// }
// })
// return roleId
// },
/**
* @author liruohao
* @date 2019/4/24
* @Description: 获取选中的部门下子子部门
*/
getDeptChild (orgId) {
return new Promise((resolve, reject) => {
this.$http.get('sys/org/getChildDept', {
orgId
}, {
_this: this
}, res => {
if (res.ok) {
// 获取组织与人员完毕,开始组装树结构
let zNodes = []
let treeNodeList = res.data
for (let i = 0; i < treeNodeList.length; i++) {
let zObj = {}
zObj.id = treeNodeList[i].id
zObj.pId = treeNodeList[i].pId
// 该节点为机构
zObj.name = treeNodeList[i].orgName
zObj.icon = 'static/images/dept.png'
zObj.isParent = true
zObj.shotName = treeNodeList[i].shotName
zObj.remarks = treeNodeList[i].remarks
zNodes[i] = zObj
}
resolve(res.data)
}
}, e => {
reject(e)
})
})
},
// 查询指定角色的人员组成树结构
getUserByRole (orgId) {
// this.getDeptChild(orgId).then(treeNodeList => {
return new Promise((resolve, reject) => {
this.loading = true
this.$http.get('sys/org/getTreeByRoleAndOrgId2', {
orgId,
roleHierarchyName: 'FO'
}, {
_this: this
}, res => {
this.loading = false
if (res.ok) {
// 获取组织与人员完毕,开始组装树结构
let treeNodeList = []
for (let i in res.data) {
let obj = {}
for (let key in res.data[i]) {
obj[key] = res.data[i][key]
}
if (!res.data[i].roleName) {
obj.icon = 'static/images/dept.png'
obj.name = obj.orgName
obj.isChecked = true
} else {
obj.icon = 'static/images/user.png'
obj.name = obj.roleName
obj.pId = obj.id
obj.id = obj.roleId
obj.isParent = false
}
treeNodeList.push(obj)
}
this.zNodesRole = treeNodeList
}
resolve()
}, e => {
this.loading = false
reject(e)
})
})
// })
}
},
watch: {
isFO (val) {
if (val) {
this.selectRoleList()
}
},
config: {
deep: true,
handler () {
// this.checkedName = this.config.valueName || this.checkedName
// if (this.config.valueName!==""){
this.checkedName = this.config.valueName || ''
// }
}
},
value (newVal, oldVal) {
this.checkedName = newVal !== '' ? this.checkedName : ''
}
},
mounted () {
this.checkedName = this.config.valueName || ''
if (this.isFO) {
this.selectRoleList()
}
}
}
</script>
<style lang="less" scoped>
.el-drawer__body{
& > div:first-child{
display: flex;
flex: auto;
flex-direction: column;
}
}
::v-deep .el-drawer__header{
&>span:first-child{
outline: none!important;
}
}
::v-deep .el-drawer{
outline: none!important;
}
</style>
@@ -0,0 +1,85 @@
<template>
<div>
<el-button @click="handleBtnCLick">点击查看</el-button>
<el-drawer
ref="drawer"
title="项目相关成员"
:visible.sync="drawerVisible"
:wrapperClosable="false"
size="600px"
:destroy-on-close="true"
append-to-body
>
<div class="demo-drawer-content">
<project-related-personnel-tree
:value="valueCopy"
@input="handleValueUpdate"
></project-related-personnel-tree>
</div>
<div class="demo-drawer-footer">
<el-button round class="common-button-primary" icon="el-icon-check" type="primary" @click="confirmDrawer('drawer')">确定</el-button>
<el-button round class="common-button-default" icon="el-icon-close" @click="closeDrawer('drawer')">取消</el-button>
</div>
</el-drawer>
</div>
</template>
<script>
import ProjectRelatedPersonnelTree from '../ProjectRelatedPersonnel/index2'
export default {
name: 'ProjectRelatedPersonnel',
components: {
ProjectRelatedPersonnelTree
},
props: ['value'],
data() {
return {
drawerVisible: false,
valueCopy: []
}
},
watch: {
value(newValue, oldValue) {
this.valueCopy = newValue
}
},
methods: {
closeDrawer(name) {
this.$refs[name].closeDrawer()
},
confirmDrawer(name) {
this.$emit('input', this.valueCopy)
this.closeDrawer(name)
},
handleValueUpdate(value) {
this.valueCopy = value
},
handleBtnCLick() {
this.valueCopy = this.value
this.drawerVisible = true
}
},
created() {
this.valueCopy = this.value
}
}
</script>
<style lang="less" scoped>
.demo-drawer-content{
overflow-y: hidden;
}
::v-deep .el-drawer__header{
&>span:first-child{
outline: none!important;
}
}
::v-deep .el-drawer{
outline: none!important;
}
</style>
@@ -0,0 +1,179 @@
<!--SVPPS组件-->
<template>
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
v-model="checkedName"
:placeholder="'请选择' + config.attrName"
readonly
:disabled="disabled"
:id="config.attrField"
@click.native="handleSVPPSClick"
/>
</el-form-item>
<el-drawer
:title="config.attrName"
:visible.sync="visible"
:wrapper-closable="false"
size="350px"
append-to-body
class="org-tree"
@opened="drawerOpen"
>
<div class="demo-drawer-content">
<laws-tree
v-if="visible"
:zNodes="zNodes"
check-enable
treeDivId="SVPPSID"
@treeOnCheck="handleOnCheck"
:editable="false"
:checkIdList="checkIdList"
:chkboxType="{ 'Y': '', 'N': '' }"
ref="SVPPSID"
:loading="svppsLoading"
class="ztree" style="height: 100%;overflow: auto"
/>
</div>
<div class="demo-drawer-footer">
<el-button
round
class="common-button-primary"
icon="el-icon-check"
type="primary"
@click="handleTreeDrawerConfirm">确定
</el-button>
<el-button
round
class="common-button-default"
icon="el-icon-close"
@click="handleTreeDrawerCancel">取消</el-button>
</div>
</el-drawer>
</el-col>
</template>
<script>
export default {
name: 'SVPPS',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
labelWidth: {
type: String,
default: '150px'
}
},
data () {
return {
visible: false,
treeCheckNode: [],
checkedName: '',
zNodes: [],
svppsLoading: false,
checkIdList: []
}
},
methods: {
getSvpps () {
this.svppsLoading = true
this.$http.get('/lawss/otSvpps/selectThree', {}, {
_this: this
}, res => {
this.svppsLoading = false
if (res.ok) {
let treeNode = []
res.data.map((item, index) => {
let treeItem = {
name: item.svppsCode + ' ' + item.svppsCnName + ' ' + item.svppsEnName,
pId: item.pid,
id: item.id,
svppsCode: item.svppsCode,
snum: item.snum,
fnum: item.fnum,
tnum: item.tnum
}
treeNode[index] = treeItem
})
this.zNodes = treeNode
}
})
},
// 选择SVPPS事件
handleOnCheck (treeCheckNode) {
this.treeCheckNode = treeCheckNode
},
// 选择SVPPS确定事件
handleTreeDrawerConfirm () {
const checkedList = []
const checkedNameList = []
if (this.treeCheckNode.length > 0) {
this.treeCheckNode.map(item => {
// if (item.pId) {
checkedList.push(item.id)
checkedNameList.push(item.svppsCode)
// }
})
this.checkedName = checkedNameList.join(',')
this.$emit('input', checkedList.join(','))
this.$emit('SVPPSName', this.checkedName)
this.$emit('on-checked', this.checkedName)
}
this.visible = false
},
// 选择SVPPS取消事件
handleTreeDrawerCancel () {
this.visible = false
},
// 赋值回显SVPPS
drawerOpen () {
this.checkIdList = this.value ? this.value.split(',') : []
},
handleSVPPSClick () {
if (this.disabled) {
return false
}
this.visible = true
}
},
watch: {
'config.valueName' () {
this.checkedName = this.config.valueName || ''
}
},
mounted () {
this.getSvpps()
this.checkedName = this.config.valueName || ''
}
}
</script>
<style lang="less" scoped>
::v-deep .el-drawer__header{
&>span:first-child{
outline: none!important;
}
}
::v-deep .el-drawer{
outline: none!important;
}
</style>
@@ -0,0 +1,221 @@
<!-- 可搜索多选框 -->
<template>
<!-- <div>-->
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
label-width="150px"
class="add-form-item"
>
<el-dropdown
trigger="click"
class="search-select"
size="medium"
>
<el-input
type="text"
readonly
:placeholder="placeholder"
v-model="selectedLabel"
suffix-icon="el-icon-arrow-down"
@click.native="visibleToggle"
:class="{ 'search-visible': visible }"
></el-input>
<el-input
type="hidden"
v-model="selectedValue"
class="el-input-hidden"
></el-input>
<el-dropdown-menu
slot="dropdown"
class="search-select-el-dropdown-menu"
>
<div class="search-input">
<el-input
v-model="searchKey"
placeholder="要搜索的内容"
class="input-color"
clearable />
</div>
<div class="search-options">
<el-dropdown-item
v-for="option in filterOptions"
:name="option.value || option.id"
:title="option.label || option.name"
:key="option.value"
:disabled="disabled"
@click.native="ondropClick(option)"
>
{{ option.label || option.name }}
</el-dropdown-item>
</div>
</el-dropdown-menu>
</el-dropdown>
</el-form-item>
</el-col>
<!-- </div>-->
</template>
<script>
export default {
name: 'searchSelect',
data () {
return {
// 显示的label
selectedLabel: '',
// 选择的value
selectedValue: '',
visible: false,
// 原始选项数据
filterOptions: [],
// 选项匹配词
searchKey: ''
}
},
methods: {
/**
* @description: 切换显示状态
* @author: chenxiaoxi
* @date: 2018/12/25 10:38:54
*/
visibleToggle () {
if (!this.disabled) {
this.visible = !this.visible
}
},
/**
* @description: 选项过滤
* @author: chenxiaoxi
* @date: 2018/12/25 10:44:38
*/
handleFilterOptions () {
// 匹配项来源
if (this.searchKey === '') {
this.filterOptions = this.options
} else {
let result = []
// 用原始数据进行匹配
if (this.options !== '' && this.options !== null) {
this.options.map((opt) => {
if (opt.label !== null && opt.label.indexOf(this.searchKey) !== -1) {
result.push(opt)
}
})
}
this.filterOptions = result
}
},
/**
* @description: 对v-model绑定的值进行匹配
* @author: chenxiaoxi
* @date: 2018/12/25 15:23:46
*/
handleValue () {
if (this.value && this.value !== '') {
if (this.options !== '' && this.options !== null) {
this.options.map((opt) => {
if (opt.value === this.value || opt.id === this.value) {
this.selectedLabel = opt.label || opt.name
this.selectedValue = opt.value || opt.id
}
})
}
} else {
this.selectedLabel = ''
this.selectedValue = ''
}
},
// 点击下拉选项事件
ondropClick (option) {
this.visible = false // 隐藏下拉菜单
this.selectedValue = option.value
this.selectedLabel = option.label
this.$emit('input', option.value) // 赋值给父组件
this.$emit('on-change', option.value) // 赋值给父组件
}
},
components: {},
props: {
value: {
type: [String, Number]
},
options: {
required: true
},
placeholder: {
type: String,
default: '请选择'
},
disabled: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: true
},
// 栅格比例
span: {
type: Number,
default: 24
}
},
computed: {},
watch: {
selectedLabel: {
deep: true,
handler (val, oldVal) {
// 当外层输入框内容清空时, 将selectedValue置为空
if (val === '') {
this.selectedValue = ''
}
}
},
// 监听显示状态
visible (val) {
if (val) {
// 当显示的时候,给选项框外绑定事件
window.addEventListener('click', function (e) {
// 点击的是搜索框外
if ($(e.target).parents('.search-select').length === 0) {
this.visible = false
}
}.bind(this))
} else {
this.searchKey = ''
}
},
// 监听关键词的变化,代替keyup事件
searchKey (val) {
this.handleFilterOptions()
},
// 监听最终选取的值
selectedValue (val) {
if (val === '' || this.selectedLabel === '') {
this.$emit('input', val)
this.$emit('on-change', val)
}
},
// 监听v-model变化
value (val) {
this.handleValue()
},
// 监听options变化
options (val, oldVal) {
this.filterOptions = JSON.parse(JSON.stringify(this.options))
this.handleValue()
}
},
mounted () {
this.filterOptions = JSON.parse(JSON.stringify(this.options))
this.handleValue()
}
}
</script>
<style lang="less">
@import '~@/assets/styles/mixins';
@import '~@/assets/styles/style';
</style>
@@ -0,0 +1,76 @@
<template>
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
label-width="150px"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-select
:value="value"
:placeholder="placeholder"
:disabled="disabled"
clearable
@change="handleChange"
>
<el-option
v-for="opt in options"
:key="opt.value"
:value="opt.value"
:label="opt.label"
>
{{ opt.label }}
</el-option>
</el-select>
</el-form-item>
</el-col>
</template>
<script>
export default {
name: 'CustomSelect',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
options () {
return this.config.options || []
}
},
methods: {
handleChange (event) {
// const value = event.target.value
this.$emit('input', event)
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,107 @@
<template>
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
label-width="150px"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-select
v-model="valueArr"
:placeholder="placeholder"
:disabled="disabled"
clearable
multiple
@change="handleChange"
>
<el-option
v-for="opt in options"
:key="opt.value"
:value="opt.value"
:label="opt.label"
>
{{ opt.label }}
</el-option>
</el-select>
</el-form-item>
</el-col>
</template>
<script>
export default {
name: 'CustomSelectArray',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
}
},
data () {
return {
valueArr: []
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
options () {
return this.config.options || []
}
},
methods: {
handleChange (event) {
// const value = event.target.value
this.$emit('input', event)
}
},
watch: {
value: {
deep: true,
handler (val) {
if (this.value !== '' && this.value !== null && typeof (this.value) !== 'undefined') {
if (this.value instanceof Array) {
this.valueArr = this.value
} else {
this.valueArr = this.value.split(',')
}
} else if (this.value === '') {
this.valueArr = []
}
}
}
},
mounted () {
if (this.value !== '' && this.value !== null && typeof (this.value) !== 'undefined') {
if (this.value instanceof Array) {
this.valueArr = this.value
} else {
this.valueArr = this.value.split(',')
}
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,69 @@
<template>
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
label-width="150px"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
type="textarea"
:value="value"
:placeholder="placeholder"
:disabled="disabled"
clearable
show-word-limit
:autosize="{minRows: 1,maxRows: 4}"
@input="handleChange"
></el-input>
</el-form-item>
</el-col>
</template>
<script>
export default {
name: 'CustomTextarea',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
}
},
methods: {
handleChange (event) {
const value = event.target.value
this.$emit('input', value)
}
}
}
</script>
<style scoped>
.standards-info-item >>> textarea {
min-height: 32px !important;
}
</style>
@@ -0,0 +1,101 @@
<template>
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
label-width="150px"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-popover
placement="bottom"
popper-class="user-dept-popper"
trigger="click"
:value="false"
>
<el-input
slot="reference"
v-model="config.attrName"
:placeholder="placeholder"
readonly
clearable
id="deptBtn1"
/>
<div class="api">
<dept-tree :treeDivId="config.attrField + 'Tree'"
:ref="config.attrField"
allDept
showUser
deptSelect
checkEnable
:editable="false"
@treeOnCheck="handleTreeOnCheck"
@onDblClick="handleTreeDblClick"
style="height: 300px;overflow: auto">
</dept-tree>
</div>
</el-popover>
</el-form-item>
</el-col>
</template>
<script>
export default {
name: 'TreePopover',
data () {
return {
treeCheckNode: [],
checkedName: ''
}
},
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
options () {
return this.config.options || []
}
},
methods: {
handleChange (event) {
// const value = event.target.value
this.$emit('input', event)
},
handleTreeOnCheck (treeCheckNode) {
this.treeCheckNode = treeCheckNode
},
handleTreeDblClick (event, treeId, treeNode) {
console.log('event, treeId, treeNode', event, treeId, treeNode)
this.$emit('input', treeNode.id)
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,103 @@
<template>
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
label-width="150px"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-popover
placement="bottom"
popper-class="user-dept-popper"
trigger="click"
:value="false"
>
<el-input
slot="reference"
:value="value"
:placeholder="placeholder"
readonly
clearable
id="deptBtn1"
/>
<div class="api">
<dept-tree
:treeDivId="config.attrField + 'Tree'"
:ref="config.attrField"
allDept
showUser
deptSelect
checkEnable
:editable="false"
@treeOnCheck="handleTreeOnCheck"
@treeDblClick="handleTreeDblClick"
style="height: 300px;overflow: auto"
>
</dept-tree>
</div>
</el-popover>
</el-form-item>
</el-col>
</template>
<script>
export default {
name: 'TreePopover',
data () {
return {
treeCheckNode: [],
checkedName: ''
}
},
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
}
},
computed: {
placeholder () {
return `请输入${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
options () {
return this.config.options || []
}
},
methods: {
handleChange (event) {
// const value = event.target.value
this.$emit('input', event)
},
handleTreeOnCheck (treeCheckNode) {
this.treeCheckNode = treeCheckNode
},
handleTreeDblClick (treeId, treeNode) {
console.log('event, treeId, treeNode', event, treeId, treeNode)
this.$emit('input', treeNode.id)
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,198 @@
<template>
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
label-width="150px"
class="add-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
:value="value"
:placeholder="'请选择' + config.attrName"
readonly
:disabled="disabled"
:id="config.attrField"
@click.native="visible = true"
/>
</el-form-item>
<el-drawer
:title="config.attrName"
:visible.sync="visible"
:wrapper-closable="false"
size="350px"
append-to-body
class="org-tree"
@opened="drawerOpen"
>
<dept-tree
:ref="config.attrField"
:all-dept="allDept"
:show-user="config.selVal === 'USERLIST'"
:check-enable="true"
:deptSelect="true"
:treeDivId="config.attrField + 'Tree'"
:editable="false"
:onlyChecked="config.attrType === 'SEL_OPTS'"
@treeOnCheck="handleTreeOnCheck"
@treeDblClick="handleTreeDblClick">
</dept-tree>
<div class="demo-drawer-footer">
<el-button
round
class="common-button-primary"
icon="el-icon-check"
type="primary"
@click="handleTreeDrawerConfirm">确定
</el-button>
<el-button
round
class="common-button-default"
icon="el-icon-close"
@click="handleTreeDrawerCancel">取消</el-button>
</div>
</el-drawer>
</el-col>
</template>
<script>
export default {
name: 'OrgTree',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 是否显示全部部门
allDept: {
type: Boolean,
default: true
},
zNodes: {
type: Array,
default: () => {
return []
}
}
},
data () {
return {
visible: false,
treeCheckNode: [],
checkedName: ''
}
},
computed: {
placeholder () {
return `请选择${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
isString (str) {
return (typeof str === 'string') && str.constructor === String
}
},
methods: {
handleTreeDblClick (treeId, treeNode) {
console.log(treeNode.id)
this.checkedName = treeNode.name
this.$emit('input', treeNode.id)
this.visible = false
},
handleTreeOnCheck (treeCheckNode) {
this.treeCheckNode = treeCheckNode
},
getShowName (id) {
let name = ''
this.zNodes.map(item => {
if (item.id === id) {
name = item.oldname || item.name
}
})
return name
},
handleTreeDrawerConfirm () {
console.log(this.config.selVal)
console.log(this.treeCheckNode)
if (this.config.selVal === 'USERLIST') {
const checkedList = []
const checkedNameList = []
this.treeCheckNode.map(item => {
if (!item.isParent) {
checkedList.push(item.id)
checkedNameList.push(item.name)
}
})
console.log(checkedNameList)
this.checkedName = checkedNameList.join(',')
console.log(this.checkedName)
this.$emit('input', checkedList.join(','))
} else {
const checkedList = []
const checkedNameList = []
this.treeCheckNode.map(item => {
checkedList.push(item.id)
if (item.oldname) {
checkedNameList.push(item.oldname)
} else {
checkedNameList.push(item.name)
}
})
this.checkedName = checkedNameList.join(',')
console.log(this.checkedName)
this.$emit('input', checkedList.join(','))
}
this.visible = false
},
handleTreeDrawerCancel () {
this.visible = false
},
// 赋值回显人员和部门
drawerOpen () {
let checkedArr = this.config.value ? this.config.value.split(',') : []
if (checkedArr.length > 0) {
setTimeout(() => {
this.$nextTick(() => {
this.$refs[this.config.attrField].checkedNode(checkedArr)
})
}, 1500)
}
}
},
watch: {
value (newVal) {
console.log(newVal)
this.checkedName = newVal || ''
},
checkedName (val) {
console.log(val)
this.$emit('update:value', val)
}
},
mounted () {
this.checkedName = this.config.valueName || ''
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,287 @@
<!--角色管理树组件-->
<template>
<!-- <el-col :span="span">-->
<span>
<el-form-item
:label="config.attrName"
:prop="config.attrField"
class="search-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
v-model="checkedName"
:placeholder="'请选择' + config.attrName"
readonly
:disabled="disabled"
:id="config.attrField"
@click.native="handleClick"
/>
</el-form-item>
<el-drawer
:title="config.attrName"
:visible.sync="visible"
:wrapper-closable="false"
size="350px"
append-to-body
destroy-on-close
>
<div class="demo-drawer-content">
<div class="search-area">
<div class="left">
<el-form inline class="label-input-form" >
<el-form-item label="角色组" class="search-item">
<el-select
v-model="roleHierarchy"
filterable
@change="roleHierarchyChange"
clearable
>
<el-option
v-for="item in roleHierarchyOption"
:key="item.id"
:value="item.id"
:label="item.name"
></el-option>
</el-select>
</el-form-item>
</el-form>
</div>
</div>
<laws-tree
v-if="visible"
:ref="config.attrField"
:zNodes="zNodes"
:treeDivId="config.attrField + 'Tree'"
:editable="false"
:chkboxType="{ 'Y': '', 'N': '' }"
:check-enable="checkEnable"
:onlyChecked="checkEnable"
deptSelect
@treeOnCheck="handleTreeOnCheck"
@treeDblClick="handleTreeDblClick"
></laws-tree>
</div>
<div class="demo-drawer-footer" v-if="checkEnable">
<el-button
round
class="common-button-primary"
icon="el-icon-check"
type="primary"
@click="handleTreeDrawerConfirm">确定
</el-button>
<el-button
round
class="common-button-default"
icon="el-icon-close"
@click="handleTreeDrawerCancel">取消</el-button>
</div>
</el-drawer>
</span>
<!-- </el-col>-->
</template>
<script>
export default {
name: 'RoleTree',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 原数据对象
dataModel: {
type: Object,
default: () => {
return {}
}
},
labelWidth: {
type: String,
default: '150px'
},
// 是否显示全部的角色树
allRole: {
type: Boolean,
default: false
},
isSearch: {
type: Boolean,
default: false
},
// 多选和单选参数
checkEnable: {
type: Boolean,
default: true
}
},
data () {
return {
visible: false,
treeCheckNode: [],
checkedName: '',
roleList: [],
loading: false,
zNodes: [],
roleHierarchy: '',
roleHierarchyOption: []
}
},
computed: {
placeholder () {
return `请选择${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
isString (str) {
return (typeof str === 'string') && str.constructor === String
},
ZRBM () {
return this.dataModel['ZRBM'] || ''
}
},
methods: {
handleClick () {
if (this.disabled) {
return false
}
this.getRoleGroup()
if (!this.allRole) {
if (this.isSearch) {
// if (!this.dataModel.orgId || this.dataModel.orgId === '') {
// this.$message.warning('请先选择部门')
// } else {
this.visible = true
this.getUserByRole(this.dataModel.orgId)
// }
} else {
// if (!this.ZRBM || this.ZRBM === '') {
// this.$message.warning('请先选择责任部门')
// } else {
this.visible = true
this.getUserByRole(this.ZRBM)
// }
}
} else {
this.visible = true
this.getUserByRole(this.ZRBM)
}
},
// 查询指定角色树
getUserByRole (orgId, roleHierarchy) {
return new Promise((resolve, reject) => {
this.loading = true
this.$http.get('sys/role/getRoleByOrgId', {
roleHierarchy,
type: 0
}, {
_this: this
}, res => {
this.loading = false
if (res.ok) {
const treeNodeList = []
for (let i = 0; i < res.data.length; i++) {
let obj = {}
for (let key in res.data[i]) {
if (key === 'usid') {
obj.id = res.data[i][key]
} else if (key === 'orgId') {
obj.pId = res.data[i][key]
} else {
obj[key] = res.data[i][key]
}
}
treeNodeList.push(obj)
}
// 获取组织与人员完毕,开始组装树结构
let zNodes = []
for (let i = 0; i < treeNodeList.length; i++) {
let zObj = {}
zObj.id = treeNodeList[i].id
zObj.pId = treeNodeList[i].pId
zObj.name = treeNodeList[i].name
zObj.icon = 'static/images/user.png'
zObj.iconSkin = 'org-user'
zObj.shotName = treeNodeList[i].shotName
zObj.remarks = treeNodeList[i].remarks
if (zObj.pId === null && !zObj.isParent) {
zObj.pId = ''
zObj.orgName = '未分配人员'
}
zNodes[i] = zObj
}
this.zNodes = zNodes
}
resolve()
}, e => {
this.loading = false
reject(e)
})
})
},
handleTreeOnCheck (treeCheckNode) {
this.treeCheckNode = treeCheckNode
},
handleTreeDrawerConfirm () {
const checkedList = []
const checkedNameList = []
this.treeCheckNode.map(item => {
checkedList.push(item.id)
checkedNameList.push(item.oldname || item.name)
})
this.checkedName = checkedNameList.join(',')
this.$emit('input', checkedList.join(','))
// this.$emit('on-checked', this.checkedName)
this.visible = false
},
handleTreeDblClick (treeId, treeNode) {
this.$emit('input', treeNode.id)
this.checkedName = treeNode.oldname || treeNode.name
this.visible = false
},
handleTreeDrawerCancel () {
this.visible = false
},
// 查询角色组
getRoleGroup () {
this.$http.get('sys/role/getRoleGroup', {}, {
_this: this
}, res => {
if (res.ok) {
this.roleHierarchyOption = res.data
}
})
},
// 角色组change查询角色树
roleHierarchyChange (val) {
this.getUserByRole(this.ZRBM, val)
}
}
}
</script>
<style lang="less" scoped>
.search-area{
padding: 10px 0 0 10px;
.search-item{
margin: 0;
}
/deep/.el-input__inner{
width: 270px !important;
}
}
</style>
@@ -0,0 +1,345 @@
<!--角色管理树组件-->
<template>
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item expand-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
:title="checkedName"
v-model="checkedName"
:placeholder="'请选择' + config.attrName"
readonly
:disabled="disabled"
:id="config.attrField"
@click.native="handleClick"
/>
</el-form-item>
<el-drawer
:title="config.attrName"
:visible.sync="visible"
:wrapper-closable="false"
size="350px"
append-to-body
@opened="drawerOpen"
>
<div class="demo-drawer-content">
<div class="search-area" v-if="isRoleHierarchy">
<div class="left">
<el-form inline class="label-input-form">
<el-form-item label="角色组" class="search-item">
<el-select
v-model="roleHierarchy"
filterable
@change="roleHierarchyChange"
clearable
>
<el-option
v-for="item in roleHierarchyOption"
:key="item.id"
:value="item.id"
:label="item.name"
></el-option>
</el-select>
</el-form-item>
</el-form>
</div>
</div>
<laws-tree
:ref="config.attrField"
:zNodes="zNodes"
:treeDivId="config.attrField + 'Tree'"
:editable="false"
:chkboxType="{ 'Y': '', 'N': '' }"
:check-enable="true"
:onlyChecked="true"
deptSelect
expandFirst
initNotCheck
:checkIdList="checkIdList"
@treeOnCheck="handleTreeOnCheck"
></laws-tree>
</div>
<div class="demo-drawer-footer">
<el-button
round
class="common-button-primary"
icon="el-icon-check"
type="primary"
@click="handleTreeDrawerConfirm">确定
</el-button>
<el-button
round
class="common-button-default"
icon="el-icon-close"
@click="handleTreeDrawerCancel">取消</el-button>
</div>
</el-drawer>
</el-col>
</template>
<script>
export default {
name: 'RoleTree',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 原数据对象
dataModel: {
type: Object,
default: () => {
return {}
}
},
labelWidth: {
type: String,
default: '150px'
},
// 是否显示全部的角色树
allRole: {
type: Boolean,
default: false
},
// 是否显示角色组下拉框
isRoleHierarchy: {
type: Boolean,
default: true
},
// 角色组名称
roleHierarchyName: {
type: String,
default: ''
}
},
data () {
return {
visible: false,
treeCheckNode: [],
checkedName: '',
roleList: [],
loading: false,
zNodes: [],
roleHierarchy: '',
roleHierarchyOption: [],
checkIdList: []
}
},
computed: {
placeholder () {
return `请选择${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
isString (str) {
return (typeof str === 'string') && str.constructor === String
},
ZRBM () {
return this.dataModel['ZRBM'] || ''
}
},
methods: {
handleClick () {
if (this.disabled) {
return false
}
this.getRoleGroup()
if (!this.allRole) {
if (!this.dataModel.ZRBM || this.dataModel.ZRBM === '') {
this.$message.warning('请先选择责任部门')
} else {
this.visible = true
this.getDeptChild().then(treeNodeList => {
this.getUserByRole(this.dataModel.ZRBM, '', this.roleHierarchyName, treeNodeList)
})
// this.getUserByRole(this.dataModel.ZRBM, '', this.roleHierarchyName)
}
} else {
this.visible = true
this.getDeptChild().then(treeNodeList => {
this.getUserByRole(this.dataModel.ZRBM, '', this.roleHierarchyName, treeNodeList)
})
}
},
// 获取选中的部门下子子部门
getDeptChild () {
return new Promise((resolve, reject) => {
this.$http.get('sys/org/getChildDept', {
orgId: this.dataModel.ZRBM
}, {
_this: this
}, res => {
if (res.ok) {
// 获取组织与人员完毕,开始组装树结构
let zNodes = []
let treeNodeList = res.data
for (let i = 0; i < treeNodeList.length; i++) {
let zObj = {}
zObj.id = treeNodeList[i].id
zObj.pId = treeNodeList[i].pId
// 该节点为机构
zObj.name = treeNodeList[i].orgName
zObj.icon = 'static/images/dept.png'
zObj.isParent = true
zObj.shotName = treeNodeList[i].shotName
zObj.remarks = treeNodeList[i].remarks
zObj.iconSkin = 'org-dept'
zNodes[i] = zObj
}
resolve(res.data)
}
}, e => {
reject(e)
})
})
},
// 查询指定角色树
getUserByRole (orgId, roleHierarchy, roleHierarchyName, treeNodeList) {
this.loading = true
this.$http.get('sys/role/getRoleByOrgId', {
orgId,
roleHierarchy,
roleHierarchyName,
type: 0
}, {
_this: this
}, res => {
this.loading = false
if (res.ok) {
for (let i = 0; i < res.data.length; i++) {
let obj = {}
for (let key in res.data[i]) {
if (key === 'usid') {
obj.id = res.data[i][key]
} else if (key === 'orgId') {
obj.pId = res.data[i][key]
} else {
obj[key] = res.data[i][key]
}
}
treeNodeList.push(obj)
}
// 获取组织与人员完毕,开始组装树结构
let zNodes = []
for (let i = 0; i < treeNodeList.length; i++) {
let zObj = {}
// 该节点为角色
if (!treeNodeList[i].orgName) {
zObj.id = treeNodeList[i].id
zObj.pId = treeNodeList[i].dyOrgId
zObj.name = treeNodeList[i].name
zObj.icon = 'static/images/user.png'
zObj.iconSkin = 'org-user'
zObj.shotName = treeNodeList[i].shotName
zObj.remarks = treeNodeList[i].remarks
} else {
// 该节点为机构
zObj.id = treeNodeList[i].id
zObj.pId = treeNodeList[i].pId
zObj.name = treeNodeList[i].orgName
zObj.oldname = treeNodeList[i].orgName
zObj.icon = 'static/images/dept.png'
zObj.iconSkin = 'org-dept'
zObj.isParent = true
zObj.isChecked = true
}
if (zObj.pId === null && !zObj.isParent) {
zObj.pId = ''
zObj.orgName = '未分配人员'
}
zNodes[i] = zObj
}
this.zNodes = zNodes
}
}, e => {
this.loading = false
})
},
handleTreeOnCheck (treeCheckNode) {
this.treeCheckNode = treeCheckNode
},
handleTreeDrawerConfirm () {
const checkedList = []
const checkedNameList = []
this.treeCheckNode.map(item => {
checkedList.push(item.id)
checkedNameList.push(item.oldname || item.name)
})
this.checkedName = checkedNameList.join(',')
this.$emit('input', checkedList.join(','))
this.$emit('on-checked', this.checkedName)
this.visible = false
},
handleTreeDrawerCancel () {
this.visible = false
},
// 查询角色组
getRoleGroup () {
this.$http.get('sys/role/getRoleGroup', {}, {
_this: this
}, res => {
if (res.ok) {
this.roleHierarchyOption = res.data
}
})
},
// 角色组change查询角色树
roleHierarchyChange (val) {
this.getDeptChild().then(treeNodeList => {
this.getUserByRole(this.dataModel.ZRBM, val, '', treeNodeList)
})
},
// 赋值回显
drawerOpen () {
this.checkIdList = this.value ? this.value.split(',') : []
},
},
watch: {
value (newVal, oldVal) {
this.checkedName = newVal !== '' ? this.checkedName : ''
}
},
mounted () {
this.checkedName = this.config.valueName || ''
}
}
</script>
<style lang="less" scoped>
.search-area{
padding: 10px 0 0 10px;
.search-item{
margin: 0;
}
/deep/.el-input__inner{
width: 270px !important;
}
}
::v-deep .el-drawer__header{
&>span:first-child{
outline: none!important;
}
}
::v-deep .el-drawer{
outline: none!important;
}
</style>
@@ -0,0 +1,337 @@
<!--角色管理树组件-->
<template>
<el-col :span="span">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item expand-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
:title="checkedName"
v-model="checkedName"
:placeholder="'请选择' + config.attrName"
readonly
:disabled="disabled"
:id="config.attrField"
@click.native="handleClick"
/>
</el-form-item>
<el-drawer
:title="config.attrName"
:visible.sync="visible"
:wrapper-closable="false"
size="350px"
append-to-body
@opened="drawerOpen"
>
<div class="demo-drawer-content">
<div class="search-area" v-if="isRoleHierarchy">
<div class="left">
<el-form inline class="label-input-form">
<el-form-item label="角色组" class="search-item">
<el-select
v-model="roleHierarchy"
filterable
@change="roleHierarchyChange"
clearable
>
<el-option
v-for="item in roleHierarchyOption"
:key="item.id"
:value="item.id"
:label="item.name"
></el-option>
</el-select>
</el-form-item>
</el-form>
</div>
</div>
<laws-tree
:ref="config.attrField"
:zNodes="zNodes"
:treeDivId="config.attrField + 'Tree'"
:editable="false"
:chkboxType="{ 'Y': '', 'N': '' }"
:check-enable="true"
:onlyChecked="true"
deptSelect
expandFirst
initNotCheck
:checkIdList="checkIdList"
@treeOnCheck="handleTreeOnCheck"
></laws-tree>
</div>
<div class="demo-drawer-footer">
<el-button
round
class="common-button-primary"
icon="el-icon-check"
type="primary"
@click="handleTreeDrawerConfirm">确定
</el-button>
<el-button
round
class="common-button-default"
icon="el-icon-close"
@click="handleTreeDrawerCancel">取消</el-button>
</div>
</el-drawer>
</el-col>
</template>
<script>
export default {
name: 'RoleTree',
props: {
config: {
type: Object,
required: true
},
value: {
required: true
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 原数据对象
dataModel: {
type: Object,
default: () => {
return {}
}
},
labelWidth: {
type: String,
default: '150px'
},
// 是否显示全部的角色树
allRole: {
type: Boolean,
default: false
},
// 是否显示角色组下拉框
isRoleHierarchy: {
type: Boolean,
default: true
},
// 角色组名称
roleHierarchyName: {
type: String,
default: ''
}
},
data () {
return {
visible: false,
treeCheckNode: [],
checkedName: '',
roleList: [],
loading: false,
zNodes: [],
roleHierarchy: '',
roleHierarchyOption: [],
checkIdList: []
}
},
computed: {
placeholder () {
return `请选择${this.config.attrName}`
},
showMessage () {
return `${this.config.attrName}不能为空`
},
isRequired () {
return !!this.config.isMust
},
isString (str) {
return (typeof str === 'string') && str.constructor === String
},
ZRBM () {
return this.dataModel['ZRBM'] || ''
}
},
methods: {
handleClick () {
if (this.disabled) {
return false
}
this.getRoleGroup()
if (!this.allRole) {
if (!this.dataModel.ZRBM || this.dataModel.ZRBM === '') {
this.$message.warning('请先选择责任部门')
} else {
this.visible = true
this.getDeptChild().then(treeNodeList => {
this.getUserByRole(this.dataModel.ZRBM, '', this.roleHierarchyName, treeNodeList)
})
// this.getUserByRole(this.dataModel.ZRBM, '', this.roleHierarchyName)
}
} else {
this.visible = true
this.getDeptChild().then(treeNodeList => {
this.getUserByRole(this.dataModel.ZRBM, '', this.roleHierarchyName, treeNodeList)
})
}
},
// 获取选中的部门下子子部门
getDeptChild () {
return new Promise((resolve, reject) => {
this.$http.get('sys/org/getChildDept', {
orgId: this.dataModel.ZRBM
}, {
_this: this
}, res => {
if (res.ok) {
// 获取组织与人员完毕,开始组装树结构
let zNodes = []
let treeNodeList = res.data
for (let i = 0; i < treeNodeList.length; i++) {
let zObj = {}
zObj.id = treeNodeList[i].id
zObj.pId = treeNodeList[i].pId
// 该节点为机构
zObj.name = treeNodeList[i].orgName
zObj.icon = 'static/images/dept.png'
zObj.isParent = true
zObj.shotName = treeNodeList[i].shotName
zObj.remarks = treeNodeList[i].remarks
zObj.iconSkin = 'org-dept'
zNodes[i] = zObj
}
resolve(res.data)
}
}, e => {
reject(e)
})
})
},
// 查询指定角色树
getUserByRole (orgId, roleHierarchy, roleHierarchyName, treeNodeList) {
this.loading = true
this.$http.get('sys/role/getRoleByOrgId', {
orgId,
roleHierarchy,
roleHierarchyName,
// type: 0
}, {
_this: this
}, res => {
this.loading = false
if (res.ok) {
for (let i = 0; i < res.data.length; i++) {
let obj = {}
for (let key in res.data[i]) {
if (key === 'usid') {
obj.id = res.data[i][key]
} else if (key === 'orgId') {
obj.pId = res.data[i][key]
} else {
obj[key] = res.data[i][key]
}
}
treeNodeList.push(obj)
}
// 获取组织与人员完毕,开始组装树结构
let zNodes = []
for (let i = 0; i < treeNodeList.length; i++) {
let zObj = {}
// 该节点为角色
if (!treeNodeList[i].orgName) {
zObj.id = treeNodeList[i].id
zObj.pId = treeNodeList[i].dyOrgId
zObj.name = treeNodeList[i].name
zObj.icon = 'static/images/user.png'
zObj.iconSkin = 'org-user'
zObj.shotName = treeNodeList[i].shotName
zObj.remarks = treeNodeList[i].remarks
} else {
// 该节点为机构
zObj.id = treeNodeList[i].id
zObj.pId = treeNodeList[i].pId
zObj.name = treeNodeList[i].orgName
zObj.oldname = treeNodeList[i].orgName
zObj.icon = 'static/images/dept.png'
zObj.iconSkin = 'org-dept'
zObj.isParent = true
zObj.isChecked = true
}
if (zObj.pId === null && !zObj.isParent) {
zObj.pId = ''
zObj.orgName = '未分配人员'
}
zNodes[i] = zObj
}
this.zNodes = zNodes
}
}, e => {
this.loading = false
})
},
handleTreeOnCheck (treeCheckNode) {
this.treeCheckNode = treeCheckNode
},
handleTreeDrawerConfirm () {
const checkedList = []
const checkedNameList = []
this.treeCheckNode.map(item => {
checkedList.push(item.id)
checkedNameList.push(item.oldname || item.name)
})
this.checkedName = checkedNameList.join(',')
this.$emit('input', checkedList.join(','))
this.$emit('on-checked', this.checkedName)
this.visible = false
},
handleTreeDrawerCancel () {
this.visible = false
},
// 查询角色组
getRoleGroup () {
this.$http.get('sys/role/getRoleGroup', {}, {
_this: this
}, res => {
if (res.ok) {
this.roleHierarchyOption = res.data
}
})
},
// 角色组change查询角色树
roleHierarchyChange (val) {
this.getDeptChild().then(treeNodeList => {
this.getUserByRole(this.dataModel.ZRBM, val, '', treeNodeList)
})
},
// 赋值回显
drawerOpen () {
this.checkIdList = this.value ? this.value.split(',') : []
},
},
watch: {
value (newVal, oldVal) {
this.checkedName = newVal !== '' ? this.checkedName : ''
}
},
mounted () {
this.checkedName = this.config.valueName || ''
}
}
</script>
<style lang="less" scoped>
.search-area{
padding: 10px 0 0 10px;
.search-item{
margin: 0;
}
/deep/.el-input__inner{
width: 270px !important;
}
}
</style>
+721
View File
@@ -0,0 +1,721 @@
<!-- 分页从全公司选择人员 -->
<template>
<div>
<!-- 弹窗,dialogModel则作为单独组件使用 -->
<el-dialog
append-to-body
:title="showTitle"
:visible.sync="isVisible"
:close-on-click-modal="false"
class="org-table"
@close="handleClose">
<div class="search-area">
<el-form
:model="searchForm"
inline
class="label-input-form"
@keyup.enter.native="handleSearch">
<el-form-item label="部门" class="search-item">
<el-input v-model="searchForm.orgId" v-show="false"/>
<el-popover
placement="bottom"
popper-class="user-dept-popper"
trigger="click"
:value="false"
>
<el-input
@mouseenter.native="handleMouseEnter"
@mouseleave.native="handleMouseLeave"
slot="reference"
v-model="searchForm.orgName"
placeholder="根据部门查询"
readonly
clearable
id="orgInput">
<i slot="suffix"
class="org el-icon-circle-close"
@click.stop="handleOrgDel"
v-show="visibleOrgClearBtn"></i>
</el-input>
<div class="api">
<laws-tree
:zNodes="orgZNodes"
ref="orgTree"
:editable="false"
treeDivId="orgTree"
deptSelect
@treeDblClick="handleSearchOrgChecked"
style="width: 200px;height: 400px;overflow: auto;">
</laws-tree>
</div>
</el-popover>
</el-form-item>
<el-form-item label="姓名" class="search-item">
<el-input
v-model="searchForm.userName"
placeholder="根据姓名查询"
clearable></el-input>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
:loading="loading.searching"
icon="el-icon-search"
type="primary"
class="common-button-primary"
round
@click="handleSearch">
</el-button>
<el-button
class="common-button-default"
icon="el-icon-refresh-left"
round
@click="handleReset"></el-button>
</el-form-item>
</el-form>
</div>
<div class="org-user">
<el-table
ref="orgTable"
:data="tableData"
tooltip-effect="dark"
style="width: 100%"
border
stripe
:header-cell-style="{ background: '#f8f8f9', color: '#515a6e' }"
height="350"
v-loading="loading.loadData"
:cell-class-name="cellClassName"
@select="selectionRow">
<el-table-column
type="selection"
width="55"
align="center"
:selectable="isSelectable">
</el-table-column>
<el-table-column
label="姓名"
width="120"
prop="userName"
align="center">
</el-table-column>
<el-table-column
prop="email"
label="邮箱"
align="center"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="roleName"
label="角色"
align="center">
<template slot-scope="scope">
<div class="tag-wrap">
<el-tag
size="small"
v-for="(tag, index) in scope.row.roleName.split(',')"
:key="index">{{ tag }}</el-tag>
</div>
</template>
</el-table-column>
<el-table-column
label="部门"
align="center">
<template #default="{ row }">{{ row.departName || row.orgName }}</template>
</el-table-column>
</el-table>
</div>
<pagination
:page="pageNo"
:pageSize="pageSize"
:total="total"
@pageChange="handlePageChange"
@pageSizeChange="handlePageSizeChange"
></pagination>
<!-- 已选择的用户 -->
<el-divider content-position="left">已选择</el-divider>
<div class="checked-user-list">
<el-tag
size="medium"
closable
v-for="item in checkedList"
:key="item.userId || item.id"
@close="handleRemove(item)">{{ item.userName || item.name }}</el-tag>
<el-button
type="danger"
size="mini"
@click="handleCleanChecked"
v-show="checkedIdList.length > 1">全部删除</el-button>
</div>
<div slot="footer" class="dialog-footer">
<el-button
type="primary"
class="common-button-primary"
icon="el-icon-check"
round
@click="handleConfirm"> </el-button>
<el-button
round
class="common-button-default"
icon="el-icon-close"
@click="handleCancel"> </el-button>
</div>
</el-dialog>
<!-- 非弹窗模式使用 -->
<el-col :span="span" v-if="!dialogModel">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item expand-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
v-model="checkedName"
:placeholder="'请选择' + config.attrName"
readonly
:disabled="disabled"
:id="config.attrField"
@click.native="handleChooseByDialog"
/>
</el-form-item>
</el-col>
</div>
</template>
<script>
import { getRoleAndUserByOrgIdPage } from 'api'
import { mapGetters } from 'vuex'
export default {
name: 'OrgTable',
mixins: [],
components: {},
props: {
title: {
type: String,
default: '组织机构'
},
visible: {
type: Boolean,
default: false
},
// 弹窗模式选取
dialogModel: {
type: Boolean,
default: false
},
config: {
type: Object
},
value: {
required: false
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 原数据对象
dataModel: {
type: Object,
default: () => {
return {}
}
},
labelWidth: {
type: String,
default: '150px'
},
maxSelected: {
type: Number
},
maxSelectedTips: {
type: String
},
// 不可选人员
excludeUser: {
type: [Array, String]
},
defaultCheck: {
type: Object
},
deptZNodes: {
type: Array
},
orgId: {
type: String
},
roleName: {
type: String
}
},
data() {
return {
isVisible: false,
visibleOrgClearBtn: false,
searchForm: {
orgId: '',
orgName: '',
userName: ''
},
tableData: [],
tableDataSelectedList: [],
pageNo: 1,
pageSize: this.configContent,
total: 0,
checkedList: [],
loading: {
searching: false,
loadData: false
},
orgZNodes: [],
// 选中节点id集合
checkedIdList: [],
// 非弹窗模式
treeCheckNode: [],
checkedName: '',
zNodesRole: [],
roleList: [],
repeatFlag: false
}
},
methods: {
handleClose() {
this.searchForm = {
orgId: '',
orgName: '',
userName: ''
}
this.pageNo = 1
this.checkedList = []
this.checkedIdList = []
this.$refs['orgTable'].clearSelection()
},
handleCancel() {
this.isVisible = false
},
handleConfirm() {
if (this.dialogModel) {
if (this.maxSelected && this.maxSelected > -1 && this.checkedList.length > this.maxSelected) {
this.$message.warning(this.maxSelectedTips || `${this.title} 只能选择一个用户`)
} else {
const checkedIdList = []
this.checkedList.map(chkItem => {
checkedIdList.push(chkItem.userId || chkItem.id)
})
this.$emit('confirm', this.checkedList, checkedIdList)
this.isVisible = false
}
} else {
switch (this.config.attrType) {
// 多选
case 'SEL_OPTS':
break
// 单选
default:
if (this.checkedList.length > 1) {
this.$message.warning(`${this.config.attrName} 只能选择一个用户`)
} else {
const dataItem = this.checkedList[0]
this.checkedName = dataItem.userName || dataItem.orgName
const id = dataItem.id || dataItem.userId
this.$emit('input', id)
this.$emit('on-checked', this.checkedName)
this.$emit('on-dept', dataItem.pOrgId, dataItem.pOrgName)
setTimeout(() => {
this.isVisible = false
}, 100)
}
}
}
},
handlePageChange(pageNo) {
this.pageNo = pageNo
this.getRoleAndUserByOrgIdPage()
},
handlePageSizeChange(pageSize) {
this.getRoleAndUserByOrgIdPage()
},
handleSearch() {
this.pageNo = 1
this.loading.searching = true
this.getRoleAndUserByOrgIdPage()
},
handleReset() {
this.pageNo = 1
this.searchForm = {
orgId: '',
orgName: '',
userName: ''
}
this.getRoleAndUserByOrgIdPage()
},
handleSearchOrgChecked(treeId, treeNode) {
this.searchForm.orgId = treeNode.id
this.searchForm.orgName = treeNode.oldname || treeNode.name
$('#orgInput').click()
},
/**
* @description: 获取组织机构
* @author: chenxiaoxi
* @time: 2021-03-21 14:40:59
*/
getOrg() {
this.$http.get('sys/org/getTree', {}, {_this: this},
res => {
if (res.ok) {
res.data.map(item => {
item.name = item.orgName
item.icon = 'static/images/dept.png'
})
this.orgZNodes = res.data
}
}, e => {})
},
/**
* @description: 分页查询用户
* @author: chenxiaoxi
* @time: 2021-03-21 17:08:06
*/
getRoleAndUserByOrgIdPage() {
this.loading.loadData = true
if (this.orgId) {
if (this.searchForm.orgId === '') {
this.searchForm.orgId = this.orgId
}
}
getRoleAndUserByOrgIdPage({
pageNo: this.pageNo,
pageSize: this.userInfo.configContent,
...this.searchForm,
roleName: this.roleName
}).then(res => {
this.loading.loadData = false
this.loading.searching = false
if (res.ok) {
this.total = res.data.count
this.tableData = res.data.list
const checkedRow = []
this.tableData.map(dataItem => {
const id = dataItem.userId || dataItem.orgId || dataItem.id
if (this.checkedIdList.includes(id)) {
checkedRow.push(dataItem)
}
})
this.checkedRow(checkedRow)
}
}).catch(e => {
this.loading.loadData = false
this.loading.searching = false
})
},
// handleRowSelect(selection, row) {
// const id = row.userId || row.id
// // 当前行选中/取消选中,其他相同用户(角色不同)被选中/取消选中
// this.tableData.map(dataItem => {
// if (dataItem.userId === id || dataItem.id === id) {
// this.$refs['orgTable'].toggleRowSelection(dataItem, selection.includes(row))
// }
// })
// console.log(this.checkedList)
// },
selectionRow(selection,row){
let selected = selection.length && selection.indexOf(row) !== -1; //为true时选中,为 0 时(false)未选中
if(selected){
selection.map(selItem => {
const id = selItem.roleId || selItem.orgId
if (!this.checkedIdList.includes(id) && !this.excludeIdList.includes(id)) {
this.checkedIdList.push(id)
this.checkedList.push(row);
}
})
} else {
this.handleRemove(row)
}
},
handleSelectionChange(selection) {
if (selection.length) {
selection.map(selItem => {
const id = selItem.userId || selItem.orgId || selItem.id
// 如果exclude不含当前行
if (!this.excludeIdList.includes(id)) {
// 如果下面列表没有,就填到下面列表里
if (!this.checkedIdList.includes(id)) {
this.checkedList.push(selItem)
this.checkedIdList.push(id)
}
} else {
// 如果exclude含当前行,当前行置为未选中状态
// this.$message.warning('主起草人/其他起草人不能为同一个人')
// this.$nextTick(() => {
// this.$refs['orgTable'].toggleRowSelection(selItem, false)
// })
}
})
}
},
handleRemove(user) {
let delIndex = -1
this.checkedList.map((checkedItem, chkIndex) => {
if (user.userId === checkedItem.userId) {
delIndex = chkIndex
return false
}
})
this.checkedList.splice(delIndex, 1)
this.checkedIdList.splice(delIndex, 1)
},
handleOrgDel() {
this.searchForm.orgId = ''
this.searchForm.orgName = ''
},
/**
* @description: 设置选中状态
* @author: chenxiaoxi
* @time: 2021-03-22 10:06:03
*/
checkedRow(rows) {
this.$nextTick(() => {
if (rows.length) {
rows.forEach(row => {
this.$refs['orgTable'] && this.$refs['orgTable'].toggleRowSelection(row)
});
} else {
this.$refs['orgTable'] && this.$refs['orgTable'].clearSelection()
}
})
},
cellClassName({row, column, rowIndex, columnIndex}) {
if (columnIndex === 3) {
return 'tag-column'
}
},
isSelectable(row, index) {
return !this.excludeIdList.includes(row.userId)
},
handleChooseByDialog() {
if (!this.dialogModel) {
this.checkedName = this.config.valueName || ''
if (this.config.value) {
this.checkedList = [{
userId: this.config.value,
userName: this.config.valueName
}]
}
const idList = this.config.value === '' || !this.config.value ? [] : this.config.value.split(',')
this.checkedIdList = [...idList]
}
this.isVisible = true
this.getRoleAndUserByOrgIdPage()
},
handleMouseEnter() {
if (this.searchForm.orgName !== '') {
this.visibleOrgClearBtn = true
}
},
handleMouseLeave() {
this.visibleOrgClearBtn = false
},
handleCleanChecked() {
this.$confirm('您是否确定移除全部已选中', '确定移除', {
confirmButtonText: '确定',
cancelButtonText: '取消',
confirmButtonClass: 'common-button-primary',
roundButton: true,
type: 'warning'
}).then(() => {
this.checkedList = []
this.checkedIdList = []
this.$refs['orgTable'].clearSelection()
}).catch(e => {})
}
},
computed: {
configContent() {
return this.userInfo.configContent
},
placeholder () {
return !this.dialogModel && `请选择${this.config.attrName}`
},
showMessage () {
return !this.dialogModel && `${this.config.attrName}不能为空`
},
isRequired () {
return !this.dialogModel && !!this.config.isMust
},
isString (str) {
return (typeof str === 'string') && str.constructor === String
},
isFO () {
return !this.dialogModel && this.config.attrField === 'FO'
},
ZRBM () {
return this.dataModel['ZRBM'] || ''
},
showTitle() {
return this.dialogModel ? this.title : this.config.attrName
},
excludeIdList() {
return this.excludeUser && this.excludeUser !== '' ? (this.excludeUser instanceof Array ? this.excludeUser : this.excludeUser.split(',')) : []
},
...mapGetters(['userInfo'])
},
watch: {
visible (val) {
this.isVisible = val
if (val) {
if (this.config.value !== '') {
const idList = this.config.value instanceof Array ? this.config.value : (this.config.value === '' ? [] : this.config.value.split(','))
const nameList = this.config.valueName instanceof Array ? this.config.valueName.split(',') : (this.config.valueName === '' ? [] : this.config.valueName.split(','))
this.checkedIdList = idList
const checkedList = []
idList.map((id, index) => {
checkedList.push({
userId: id,
userName: nameList[index]
})
})
this.checkedList = checkedList
}
this.getRoleAndUserByOrgIdPage()
}
},
isVisible (val) {
this.$emit('update:visible', val)
},
value (newVal, oldVal) {
this.checkedName = newVal !== '' ? this.checkedName : ''
},
deptZNodes: {
handler (val) {
this.orgZNodes = val
}
}
},
mounted() {
this.isVisible = this.visible
if (!this.dialogModel) {
this.checkedName = this.config.valueName || ''
if (this.config.value !== '') {
this.checkedList = [{
userId: this.config.value,
userName: this.config.valueName
}]
const idList = this.config.value === '' ? [] : this.config.value.split(',')
this.checkedIdList = [...idList]
}
} else {
const idList = this.config.value instanceof Array ? this.config.value : (this.config.value === '' ? [] : this.config.value.split(','))
const nameList = this.config.valueName instanceof Array ? this.config.valueName.split(',') : (this.config.valueName === '' ? [] : this.config.valueName.split(','))
this.checkedIdList = idList
const checkedList = []
idList.map((id, index) => {
checkedList.push({
userId: id,
userName: nameList[index]
})
})
this.checkedList = checkedList
}
this.getOrg()
this.getRoleAndUserByOrgIdPage()
}
}
</script>
<style lang="less" scoped>
.org-table {
/deep/ .el-dialog__header {
padding: 0 20px;
height: 50px;
display: flex;
align-items: center;
border-bottom: 1px solid #ddd;
}
/deep/ .el-dialog__body {
padding: 15px 20px 20px 20px;
}
.search-area {
padding: 0;
/deep/ .el-form-item__label {
line-height: 35px;
}
/deep/ .el-form-item__content {
line-height: 35px;
.el-input__inner {
height: 35px;
line-height: 35px;
}
}
}
.pagination {
position: static;
}
.checked-user-list {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
.el-tag {
margin: 0 10px 10px 0;
}
.el-button--mini {
padding: 0 15px;
height: 28px;
line-height: 28px;
}
}
}
/deep/ .el-popover__reference-wrapper {
.el-input__suffix {
padding-right: 5px;
&:hover {
cursor: pointer;
}
}
}
/deep/ .tag-column {
.cell {
padding: 5px 10px;
overflow: visible;
text-overflow: clip;
.tag-wrap {
.el-tag {
height: auto;
white-space: normal;
text-align: left;
}
}
}
}
</style>
@@ -0,0 +1,126 @@
# 表格选人组件说明文档(2021-03上汽全公司选人解决方案)
### 1,主要实现功能
- 弹窗模式+自己写的输入框选人
- 自定义表单组件选人(默认输入框+选人)
- 人员单选
- 人员多选
- 已选择项反选
- 控制不可添加人员
- 搜索(按机构、按姓名)
### 2,参数说明
```
title: {
type: String,
default: '组织机构'
},
visible: {
type: Boolean,
default: false
},
// 弹窗模式选取
dialogModel: {
type: Boolean,
default: false
},
config: {
type: Object
},
value: {
required: false
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 原数据对象
dataModel: {
type: Object,
default: () => {
return {}
}
},
labelWidth: {
type: String,
default: '150px'
},
maxSelected: {
type: Number
},
maxSelectedTips: {
type: String
},
// 不可选人员
excludeUser: {
type: [Array, String]
}
```
- title 字符串-默认值"组织机构",弹窗模式下定义标题
- visible 布尔-默认值false,弹窗模式下弹窗是否可见
- dialogModel 布尔-默认值false,是否为弹窗模式,默认false时为自定义表单中使用
- config 对象-没有默认值 ,自定义表单会带这个东西,弹窗模式的时候需要传一个value和一个valueName用于回显
- value 字符串-没有默认值,非弹窗模式需要传,就是原来自定义表单用custom-org直接标签改成org-table就行
- disabled 禁用,非弹窗模式用的
- span 非弹窗用的,栅格
- dataModel 原始数据对象,我忘了干啥的了,从org组件复制的,弹窗模式不用传
- labelWidth 自定义表单中的label宽度
- maxSelected 弹窗模式中传,最多能选几个人
- maxSelectedTips 超过最多选的人的提示,有默认提示语不传也行
- excludeUser 非弹窗模式传的,不可选的人,比如需求主起草不能为其他起草人,id组成的数组或者逗号字符串
### 3,示例
```
<!-- 弹窗使用 采购翻译流程-采购处理人(上汽全公司选人解决方案) -->
<org-table
title="采购处理人"
:visible.sync="visibleOrgTable"
dialog-model
:config="orgTableConfig"
:max-selected="1"
max-selected-tips="采购处理人只能为一个人"
@confirm="handleOrgTableConfirm"
></org-table>
visibleOrgTable: false, // 弹窗是否可见
orgTableConfig: {
value: '', // 回显用的userId逗号拼接的字符串
valueName: '' // 回显用的userName逗号拼接的字符串
}
checkedList 是userId+userName组成的对象 [{userId: xx, userName: xx}]
handleOrgTableConfirm(checkedList, checkedIdList) {
let findIndex = -1
let row = {}
this.tableData.map((item, index) => {
if (item.id === this.id) {
row = JSON.parse(JSON.stringify(item))
findIndex = index
}
})
row.handler = checkedList[0].userId
row.handlerName = checkedList[0].userName
row.handlerRul = true
this.$set(this.tableData, findIndex, row)
}
```
```
<!-- 自定义表单中使用,原来custom-org咋用这个就咋用 -->
<template v-else-if="field.attrField === 'FGWHR'">
<org-table
:key="field.attrField"
:config="field"
:zNodes="orgData"
v-model="sarStandardsInfoEO[field.attrField]"
:disabled="formdisableflag"
:data-model="sarStandardsInfoEO"
></org-table>
</template>
```
@@ -0,0 +1,318 @@
<!-- 流程组织机构树 -->
<template>
<div class="dept-tree">
<laws-tree
ref="roleTree"
:treeDivId="treeDivId"
:zNodes="zNodes"
:expandAll="expandAll"
:editable="editable"
:deptSelect="deptSelect"
:pIdCheck="pIdCheck"
:checkEnable="checkEnable"
:loading="loading.treeLoading"
:onlyChecked="onlyChecked"
:chkboxType="chkboxType"
:checkIdList="checkIdList"
role
@treeClick="(treeId, treeNode) => treeClick(treeId, treeNode)"
@treeOnExpand="(treeId, treeNode) => treeOnExpand(treeId, treeNode)"
@treeDblClick="(treeId, treeNode) => treeDblClick(treeId, treeNode)"
@treeReady="treeReady"
@treeOnCheck="(checkedList) => treeOnCheck(checkedList)"
></laws-tree>
</div>
</template>
<script>
import eventHub from '@/common/eventHub'
export default {
name: 'RoleTree',
data () {
return {
dept: [], // 部门节点
deptUser: [], // 部门人员节点
projectManagerzNodes: [],
loading: {
treeLoading: false
},
zNodes: []
}
},
methods: {
// 节点点击
treeClick (treeId, treeNode) {
this.$emit('treeClick', treeId, treeNode)
},
// 节点双击
treeDblClick (treeId, treeNode) {
this.$emit('treeDblClick', treeId, treeNode)
},
// 节点展开
treeOnExpand (treeId, treeNode) {
// this.$emit('treeOnExpand', treeId, treeNode)
},
// 首次加载完成
treeReady () {
this.$emit('treeReady')
},
// 节点重新加载
treeReload () {
this.$refs.deptTree.lawsTreeInit()
},
// 选择节点复选框事件
treeOnCheck (checkedList) {
const personCheckedNameList = []
const personCheckedIdList = []
checkedList.map(item => {
if (item.orgName) {
personCheckedNameList.push(item.name)
personCheckedIdList.push(item.id)
}
})
const personCheckedId = personCheckedIdList.join(',')
const personCheckedName = personCheckedNameList.join(',')
this.$emit('treeOnCheck', checkedList)
this.$emit('personCheck', personCheckedId, personCheckedName)
},
// 回显选中checked节点
checkedNode (checkedNodes) {
this.$refs.deptTree.checkedNode(checkedNodes)
},
/**
* @description: 选中节点移除
* @author: chenxiaoxi
* @date: 2018/10/29 14:42:02
*/
removeNode (treeNode) {
this.$refs.deptTree.removeNode(treeNode)
},
/**
* @description: 节点添加
* @author: chenxiaoxi
* @date: 2018/10/29 14:53:24
*/
addNode (treeNode) {
this.$refs.deptTree.addNode(treeNode)
},
/**
* @description: 节点取消选中
* @author: chenxiaoxi
* @date: 2018/10/29 16:09:11
*/
cancelSelectedNode (treeNode) {
if (treeNode !== '' && treeNode !== undefined) {
this.$refs.deptTree.cancelSelectedNode(treeNode)
} else {
this.$refs.deptTree.cancelSelectedNode()
}
},
/**
* @description: 节点选中
* @author: chenxiaoxi
* @date: 2018/10/29 16:14:23
*/
selectNode (treeNode) {
if (treeNode !== '' && treeNode !== undefined) {
this.$refs.deptTree.selectNode(treeNode)
}
},
/**
* @description: 获取选中节点
* @author: chenxiaoxi
* @date: 2018/10/29 16:14:23
*/
getSelectNode (idList) {
return this.$refs.deptTree.getSelectNode(idList)
},
/**
* @description: 保存打开的节点
* @author: chenxiaoxi
* @date: 2018/11/23 16:37:01
*/
setOpenNodes () {
this.$refs.deptTree.setOpenNodes()
},
/**
* @description: 清空过滤输入框
* @author: chenxiaoxi
* @date: 2018/11/23 16:52:10
*/
clearSearch () {
this.$refs.deptTree.clearSearch()
},
// 查询指定角色树
getUserByRole (orgId, roleHierarchy) {
this.isTree = true
return new Promise((resolve, reject) => {
this.loading = true
this.$http.get('sys/role/getRoleByOrgId', {
orgId,
roleHierarchy,
type: 0
}, {
_this: this
}, res => {
this.loading = false
if (res.ok) {
const treeNodeList = res.data
// 获取组织与人员完毕,开始组装树结构
let zNodes = []
for (let i = 0; i < treeNodeList.length; i++) {
let zObj = {...treeNodeList[i]}
zObj.pId = treeNodeList[i].pId || '000000'
zObj.name = treeNodeList[i].name
zObj.icon = 'static/images/dept.png'
zObj.iconSkin = 'org-user'
zObj.shotName = treeNodeList[i].shotName
zObj.remarks = treeNodeList[i].remarks
zObj.dyOrgName = treeNodeList[i].dyOrgName
zObj.dyOrgId = treeNodeList[i].dyOrgId
zObj.type = 'role'
zNodes[i] = zObj
}
this.zNodes = zNodes
}
resolve()
}, e => {
this.loading = false
reject(e)
})
})
}
},
components: {},
props: {
// 是否显示组织下的用户
showUser: {
type: Boolean,
default: false
},
// 是否禁用
disabled: {
type: Boolean,
default: false
},
// 部门节点
zNodesDept: {
type: Array
},
// 部门人员节点
zNodesDeptUser: {
type: Array
},
// 是否可进行操作
editable: {
type: Boolean,
default: true
},
// 部门是否可以被选择
deptSelect: {
type: Boolean,
default: false
},
// 树实例Id
treeDivId: {
type: String
},
// 是否获取所有组织
allDept: {
type: Boolean,
default: false
},
// 是否根据责任部门查找经理
department: {
type: Array
},
// 需要回显的节点
idList: {
type: Array,
required: false
},
// 回显的部门节点
deptList: {
type: Array
},
// 是否展开全部
expandAll: {
type: Boolean,
default: false
},
// 不选中根节点
pIdCheck: {
type: Boolean,
default: false
},
// 是否开启复选框
checkEnable: {
type: Boolean,
default: false
},
// 只能checkbox选中,不能点击选中节点
onlyChecked: {
type: Boolean,
default: false
},
chkboxType: {
type: Object,
default: () => {
return {'Y': 'ps', 'N': 'ps'}
}
},
// checkbox需要选中的节点
checkIdList: {
type: Array,
default: () => {
return []
}
}
},
computed: {
// 节点(给lawsTree传的节点,根据展示的类型传不同的值)
// zNodes () {
// return this.showUser ? (this.zNodesDeptUser || this.deptUser) : (this.projectManagerzNodes.length === 0 ? (this.zNodesDept || this.dept) : this.projectManagerzNodes)
// }
},
watch: {
zNodes (val) {
this.$nextTick(() => {
if (this.idList && this.idList.length) {
let deptUser = this.$refs.deptTree.getSelectNode(this.idList)
this.$emit('selectNodeUser', deptUser)
}
})
},
deptList (val) {
if (val.length) {
let zNodes = this.showUser ? (this.zNodesDeptUser || this.deptUser) : (this.zNodesDept || this.dept)
for (let i = 0; i < zNodes.length; i++) {
val.map((displayNode) => {
if (zNodes[i].id === displayNode.id) {
zNodes.splice(i, 1)
}
})
}
}
}
},
mounted () {
this.getUserByRole()
}
}
</script>
<style lang="less">
.dept-tree{
height: 100%;
}
</style>
@@ -0,0 +1,278 @@
<!--项目相关人员-->
<template>
<div class="tree__wrapper">
<div class="item">
<dept-tree
treeDivId="selectTree"
ref="selectTree"
showUser
allDept
deptSelect
style="width: 200px;height: 500px;overflow: auto"
:editable="false"
@treeClick="handleSelectTreeClick"
@treeDblClick=""
>
</dept-tree>
</div>
<div class="item btn__wrapper">
<el-button
type="primary"
icon="el-icon-arrow-right"
@click="toResultTree"
></el-button>
</div>
<div class="item">
<laws-tree2
treeDivId="resultTree"
ref="resultTree"
:zNodes="resultNodes"
:autoSelect="false"
deptSelect
style="width: 200px;height: 500px;overflow: auto"
editable
showRMenu
:show-r-menu-add="false"
:show-r-menu-copy="false"
@treeClick="handleResultTreeClick"
@treeDblClick=""
@treeRemove="handleResultTreeRemove"
@treeEdit="handleResultTreeEdit"
>
</laws-tree2>
</div>
<el-dialog
title="编辑角色"
:visible.sync="editNodeDialogVisible"
destroy-on-close
append-to-body
width="60%">
<el-form ref="editNode" :model="editNodeForForm" class="label-input-form" label-width="130px">
<el-formItem label="角色" prop="title" class="add-form-item">
<el-input v-model="editNodeForForm.wxRole" placeholder="请输入角色"></el-input>
</el-formItem>
</el-form>
<div slot="footer" class="demo-drawer-footer">
<el-button type="primary" round class="common-button-primary" icon="el-icon-check" @click="editNodeDialogSubmit">确定</el-button>
<el-button round class="common-button-default" icon="el-icon-close" @click="editNodeDialogVisible = false">取消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import lawsTree2 from '@/components/lawsTree/index2'
let wxId = 0
const rootNode = {
id: '-1',
name: '根节点',
nativeName: '根节点',
icon: 'static/images/dept.png',
wxId: -1,
type: 'root',
wxRole: ''
}
const checkNodeTypeByIcon = (data) => {
const matcher = {
'static/images/dept.png': 'dept',
'static/images/user.png': 'user'
}
return data.type || matcher[data.icon]
}
const checkNodeIconByType = (data) => {
const matcher = {
'dept': 'static/images/dept.png',
'user': 'static/images/user.png'
}
return data.icon || matcher[data.type]
}
const resolveNameByType = (data) => {
if (data.type === 'dept') {
return data.orgName
} else {
return data.userName
}
}
export default {
name: 'index',
components: {
lawsTree2
},
props: ['value'],
data() {
return {
selectNode: {}, // 左侧选中的节点数据
resultNode: {}, // 右侧选中的节点数据
resultNodes: [], // 右侧树数据
editNode: {},
editNodeForForm: {},
editNodeDialogVisible: false
}
},
watch:{
value(newValue, oldValue) {
console.log(newValue)
this.resolveValueToResultNodes(newValue)
}
},
methods: {
handleSelectTreeClick(treeId, treeNode) {
console.log(treeId, treeNode)
this.selectNode = { ...treeNode }
},
handleResultTreeClick(treeId, treeNode) {
this.resultNode = { ...treeNode }
},
toResultTree() {
if (this.resultNode.id || this.resultNode.name) {
// 判断是否为相同节点
if (this.resultNode.id === this.selectNode.id) {
this.$message.warning("请选择右侧其他不相同的节点")
return
}
if (this.checkHasNode(this.selectNode.id, this.resultNode.id)) {
this.$message.warning("右侧当前层级已存在相同节点")
return
}
if (!this.selectNode.id && !this.selectNode.name) {
this.$message.warning("请选择左侧节点")
return
}
const treeNode = {
id: this.selectNode.id,
name: this.selectNode.name,
nativeName: this.selectNode.name,
icon: this.selectNode.icon,
pId: this.resultNode.id,
wxId: wxId++,
type: checkNodeTypeByIcon(this.selectNode),
wxRole: ''
}
this.$refs['resultTree'].addNode(treeNode)
this.emitInput()
} else {
this.$message.warning("请选择右侧节点")
}
},
checkHasNode(id, pId) {
return this.resultNodes.some(item => item.pId === pId && item.id === id)
},
handleResultTreeRemove(treeId, treeNode) {
const wxId = treeNode.wxId
const findIndex = this.resultNodes.findIndex(item => item.wxId === wxId)
if (findIndex > -1) {
this.resultNodes.splice(findIndex, 1)
}
this.emitInput()
},
handleResultTreeEdit(treeId, treeNode) {
const wxId = treeNode.wxId
const findNode = this.resultNodes.find(item => item.wxId === wxId)
console.log(findNode)
if (findNode && findNode.type === 'user') {
this.editNode = findNode
this.editNodeForForm = { ...findNode }
this.editNodeDialogVisible = true
} else {
this.$message.warning('当前节点不可编辑角色')
}
},
editNodeDialogSubmit() {
this.editNode.wxRole = this.editNodeForForm.wxRole
// 用户的显示需要 用户名+角色
let nameAndRole = this.editNode.nativeName
if (this.editNode.type === 'user' && this.editNode.wxRole) {
nameAndRole = this.editNode.nativeName + ' - ' + this.editNode.roleName
}
this.editNodeDialogVisible = false
this.emitInput()
},
emitInput() {
const list = [...this.resultNodes]
// 去掉根节点
list.shift()
const result = list.map(item => {
const pId = item.pId === '-1' ? '' : item.pId
return {
tsId: item.id,
pid: pId,
roleName: item.wxRole,
type: item.type,
orgName: item.type === 'dept' && item.nativeName || null,
userName: item.type === 'user' && item.nativeName || null
}
})
console.log(result)
this.$emit('input', result)
},
resolveValueToResultNodes() {
const value = this.value || []
const result = value.map(item => {
const pId = item.pid || '-1'
const name = resolveNameByType(item)
// 用户的显示需要 用户名+角色
let nameAndRole = name
if (item.type === 'user' && item.roleName) {
nameAndRole = name + ' - ' + item.roleName
}
return {
id: item.tsId,
nativeName: name,
name: nameAndRole,
icon: checkNodeIconByType(item),
pId: pId,
wxId: item.id || wxId++,
type: item.type,
wxRole: item.roleName || ''
}
})
this.resultNodes = [rootNode, ...result]
}
},
created() {
this.resolveValueToResultNodes()
}
}
</script>
<style lang="less" scoped>
.tree__wrapper {
display: flex;
justify-content: space-between;
.item {
flex: 1 1 200px;
}
.btn__wrapper {
flex: 0 0 60px;
padding: 10px;
align-self: center;
}
}
</style>
@@ -0,0 +1,523 @@
<!--项目相关人员-->
<template>
<div style="flex: auto;position: relative;">
<div class="singleBox">
<el-popover
placement="right"
width="330"
trigger="manual"
v-model="visible">
<div class="proper">
<i class="el-icon-close" @click="visible = false"></i>
<label>项目名称:</label>
<el-select class="inp" v-model="productname" filterable placeholder="节点快速查找" @focus="getNativeName" @change="getProductUserList">
<el-option
v-for="item in gridData"
:key="item.productId"
:label="item.productName"
:value="item.id">
</el-option>
</el-select>
</div>
<el-button class="bt" round size="small" type="primary" slot="reference" @click="visible = !visible">复制</el-button>
</el-popover>
<div class="tree__wrapper">
<div class="item">
<role-tree
treeDivId="selectTree"
ref="selectTree"
deptSelect
style="width: 200px;overflow: auto"
:editable="false"
@treeClick="handleSelectTreeClick"
@treeDblClick=""
>
</role-tree>
</div>
<div class="item btn__wrapper">
<el-button
type="primary"
icon="el-icon-arrow-right"
@click="toResultTree"
></el-button>
</div>
<div class="item">
<laws-tree2
treeDivId="resultTree"
ref="resultTree"
:zNodes="resultNodes"
:autoSelect="false"
deptSelect
style="width: 200px;overflow: auto"
editable
showRMenu
:show-r-menu-add="false"
:show-r-menu-copy="false"
@treeClick="handleResultTreeClick"
@treeDblClick=""
@treeRemove="handleResultTreeRemove"
@treeEdit="handleResultTreeEdit"
>
</laws-tree2>
</div>
<!-- <role-user-tree-->
<!-- :visible.sync="editNodeDialogVisible"-->
<!-- checkEnable-->
<!-- :checkIdList="checkIdList"-->
<!-- @confirm="confirm"-->
<!-- ></role-user-tree>-->
<org-table :visible.sync="editNodeDialogVisible" dialog-model @confirm="confirm" :config="orgValChecked"></org-table>
<!--<el-dialog-->
<!-- title="编辑角色"-->
<!-- :visible.sync="editNodeDialogVisible"-->
<!-- destroy-on-close-->
<!-- append-to-body-->
<!-- width="60%">-->
<!-- <div slot="footer" class="demo-drawer-footer">-->
<!-- <el-button type="primary" round class="common-button-primary" icon="el-icon-check" @click="editNodeDialogSubmit">确定</el-button>-->
<!-- <el-button round class="common-button-default" icon="el-icon-close" @click="editNodeDialogVisible = false">取消</el-button>-->
<!-- </div>-->
<!--</el-dialog>-->
</div>
</div>
</div>
</template>
<script>
import lawsTree2 from '@/components/lawsTree/index2'
import RoleTree from './components/RoleTree'
let wxId = 0
const rootNode = {
open: true,
id: '-1',
name: '项目成员',
nativeName: '项目成员',
icon: 'static/images/dept.png',
wxId: -1,
type: 'root',
wxRole: '',
userList: []
}
const checkNodeTypeByIcon = (data) => {
const matcher = {
'static/images/dept.png': 'role',
'static/images/user.png': 'user'
}
return data.type || matcher[data.icon]
}
const checkNodeIconByType = (data) => {
const matcher = {
'role': 'static/images/dept.png',
'user': 'static/images/user.png'
}
return data.icon || matcher[data.type]
}
const resolveNameByType = (data) => {
if (data.type === 'role') {
return data.roleName
} else {
return data.userName
}
}
export default {
name: 'index',
components: {
lawsTree2,
RoleTree
},
props: ['value'],
data() {
return {
gridData:[],
productname:'',
visible:false,
selectNode: {}, // 左侧选中的节点数据
resultNode: {}, // 右侧选中的节点数据
resultNodes: [], // 右侧树数据
editNode: {},
editNodeForForm: {},
editNodeDialogVisible: false,
checkIdList: [],
orgValChecked: {
value: '',
valueName: ''
},
checkList: []
}
},
watch:{
value(newValue, oldValue) {
this.resolveValueToResultNodes(newValue)
}
},
methods: {
handleSelectTreeClick(treeId, treeNode) {
this.selectNode = { ...treeNode }
},
handleResultTreeClick(treeId, treeNode) {
this.resultNode = { ...treeNode }
},
toResultTree() {
if (this.resultNode.id || this.resultNode.name) {
// 判断是否为相同节点
if (this.resultNode.id === this.selectNode.id) {
this.$message.warning("请选择右侧其他不相同的节点")
return
}
if (this.checkHasNode(this.selectNode.id, this.resultNode.id)) {
this.$message.warning("右侧当前层级已存在相同节点")
return
}
if (!this.selectNode.id && !this.selectNode.name) {
this.$message.warning("请选择左侧节点")
return
}
const treeNode = {
id: this.selectNode.id,
name: this.selectNode.name,
nativeName: this.selectNode.name,
icon: this.selectNode.icon,
pId: this.resultNode.id,
wxId: wxId++,
type: checkNodeTypeByIcon(this.selectNode),
wxRole: this.selectNode.id,
roleCode: this.selectNode.id,
roleName: this.selectNode.name,
userList: [],
__treeNode__: this.selectNode
}
this.$refs['resultTree'].addNode(treeNode)
this.emitInput()
} else {
this.$message.warning("请选择右侧节点")
}
},
checkHasNode(id, pId) {
return this.resultNodes.some(item => item.pId === pId && item.id === id)
},
handleResultTreeRemove(treeId, treeNode) {
const wxId = treeNode.wxId
const findIndex = this.resultNodes.findIndex(item => item.wxId === wxId)
if (findIndex > -1) {
this.resultNodes.splice(findIndex, 1)
}
this.emitInput()
},
handleResultTreeEdit(treeId, treeNode) {
const wxId = treeNode.wxId
const findNode = this.resultNodes.find(item => item.wxId === wxId)
if (findNode && findNode.type === 'role') {
this.editNode = findNode
this.editNodeForForm = { ...findNode, userList: [] }
this.checkIdList = treeNode.userList.length > 0 ? treeNode.userList[0].id.split(',') : []
this.checkList = treeNode.userList
const idList = []
const nameList = []
treeNode.userList.map(item => {
if (item.userId) {
idList.push(item.userId)
} else {
idList.push(item.id)
}
if (item.userName) {
nameList.push(item.userName)
} else {
nameList.push(item.name)
}
})
this.orgValChecked = {
value: idList.join(','),
valueName: nameList.join(',')
}
this.editNodeDialogVisible = true
} else {
this.$message.warning('当前节点不可维护用户')
}
},
editNodeDialogSubmit() {
this.editNode.userList = this.editNodeForForm.userList
// 用户的显示需要 用户名+角色
let nameAndRole = this.editNode.nativeName
if (this.editNode.type === 'role' && this.editNode.userList && this.editNode.userList.length > 0) {
const userName = this.editNode.userList.map(item => item.userName || item.oldname || item.name)
const showName = userName.join(',')
nameAndRole = this.editNode.nativeName + ' (' + showName + ')'
}
this.editNodeDialogVisible = false
this.emitInput()
},
emitInput() {
const list = [...this.resultNodes]
// 去掉根节点
list.shift()
const result = list.map(item => {
const pId = item.pId === '-1' ? '' : item.pId
const userIdArr = item.userList.map(item => item.userId || item.id)
const userNameArr = item.userList.map(item => item.userName || item.oldname || item.name)
return {
tsId: userIdArr.join(','),
pid: pId,
type: item.type,
roleName: item.type === 'role' && item.nativeName || null,
roleCode: item.roleCode,
userList: [...item.userList],
userName: userNameArr.join(',')
}
})
this.$emit('input', result)
},
resolveValueToResultNodes() {
const value = this.value || []
const result = value.map(item => {
const pId = item.pid || '-1'
const tsid =item.tsId
const tsidArr = tsid ? tsid.split(',') : []
const name1 = item.userName
const nameArr = name1 ? name1.split(',') : []
const userList = tsidArr.map((item, index) => {
return {
id: item,
name:nameArr[index]
}
})
// if (item.tsId) {
// userList.push({id: item.tsId, name: item.userName})
// }
const name = resolveNameByType(item)
// 用户的显示需要 用户名+角色
let nameAndRole = name
if (item.type === 'role' && userList && userList.length > 0) {
const userName = userList.map(item => item.name)
nameAndRole = name + ' (' + userName + ')'
}
return {
open: true,
id: item.roleCode,
roleCode: item.roleCode,
roleName: item.roleName,
nativeName: name,
name: nameAndRole,
icon: checkNodeIconByType(item),
pId: pId,
wxId: item.id || wxId++,
type: item.type,
userList: userList || []
}
})
this.resultNodes = [rootNode, ...result]
},
confirm(checkedList) {
this.editNodeForForm.userList = checkedList
this.editNodeDialogSubmit()
},
arraySplit(item){
for (let i = 0;i<item.length;i++){
const id = item.id
const idArr = id ? id.split(',') : []
const name = item.name
const nameArr = name ? name.split(',') : []
debugger
const userList = id.map((item, index) => {
return {
id: item,
name:nameArr[index]
}
})
}},
//获取所有项目信息
getNativeName(){
this.$http.get('lawss/sarProductInfo/queryAllProjectInfo',{},{
_this : this
}, res => {
this.gridData = res.data
this.gridData.productId = res.data.id
})
},
getProductUserList(value){
this.$http.get('lawss/sarProductUser/getUserListByProjectId',{
productId : value
},{
_this : this
}, res => {
if (res.ok){
const list = []
//角色拆分
for (let i = 0;i<res.data.length;i++){
const tsid = res.data[i].tsId
const tsidArr = tsid ? tsid.split(',') : []
const name = res.data[i].userName
const nameArr = name ? name.split(',') : []
const userList = tsidArr.map((item, index) => {
return {
id: item,
name:nameArr[index]
}
})
const resultList1 = {
id: res.data[i].roleCode,
name: res.data[i].roleName,
nativeName: res.data[i].roleName,
icon: checkNodeIconByType(res.data[i]),
pId:res.data[i].pid,
wxId: wxId++,
type: checkNodeTypeByIcon(res.data[i]),
wxRole: res.data[i].roleCode,
roleCode: res.data[i].roleCode,
roleName: res.data[i].roleName,
userList: userList,
__treeNode__: res.data[i],
}
if (resultList1.pId === ''){
resultList1.pId = '-1'
}else {
resultList1.pId = res.data[i].pid
}
list.push(resultList1)
}
//节点去重
const idList=[]
this.resultNodes.forEach(item =>{
idList[item.id+'-'+item.pId] = item
})
const idListHas=[]
const idListNo=[]
list.forEach(item => {
if (!!idList[item.id + '-' + item.pId]) {
idListHas.push(item)
} else {
idListNo.push(item)
}
})
for (let i = 0;i<idListNo.length;i++){
this.resultNodes.push(idListNo[i])
}
//角色去重
const UserListMapHas=[]
const UserListMapNo=[]
const idListUserMap={}
idListHas.forEach(item =>{
const idUserMap = idList[item.id+'-'+item.pId]
idUserMap.userList.forEach(i =>{
idListUserMap[i.id+'-'+i.name] = i
})
item.userList.forEach(i =>{
if (idListUserMap[i.id+'-'+i.name]){
UserListMapHas.push(i)
}else {
UserListMapNo.push(i)
}
})
for (let i=0;i<UserListMapNo.length;i++){
idUserMap.userList.push(UserListMapNo[i])
}
}
)
this.emitInput()
}
})
}
},
created() {
this.resolveValueToResultNodes()
}
}
</script>
<style lang="less" scoped>
.singleBox {
flex: auto;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.tree__wrapper {
display: flex;
justify-content: space-between;
height: 100%;
.item {
flex: 1 1 200px;
display: flex;
flex-direction: column;
}
.btn__wrapper {
flex: 0 0 60px;
padding: 10px;
align-self: center;
}
}
</style>
<style scoped>
.proper i{
float: right;
margin-top: -10px;
cursor: pointer;
}
.bt {
float: right;
margin-top: 10px;
}
.inp{
width: 230px;
border-radius: 50px;
margin-left: 5px;
}
/deep/.el-input--suffix .el-input__inner {
border-radius: 100px;
height: 35px;
line-height: 35px;
}
.proper{
font-size: 12px;
}
/deep/.inp .el-input{
font-size: 12px!important;
}
/deep/ .el-input__icon {
line-height: 35px!important;
}
::v-deep .el-scrollbar .el-select-dropdown__item{
font-size: 12px!important;
height: 24px!important;
line-height: 24px!important;
}
</style>
@@ -0,0 +1,129 @@
<!--项目相关人员-->
<template>
<div class="tree__wrapper">
<laws-tree2
treeDivId="resultTree"
ref="resultTree"
:zNodes="resultNodes"
:autoSelect="false"
style="width: 100%;height: 500px;overflow: auto"
:editable="false"
>
</laws-tree2>
</div>
</template>
<script>
import lawsTree2 from '@/components/lawsTree/index2'
let wxId = 0
const rootNode = {
open: true,
id: '-1',
name: '项目成员',
icon: 'static/images/dept.png',
wxId: -1,
type: 'root',
wxRole: '',
userList: []
}
const checkNodeIconByType = (data) => {
const matcher = {
'role': 'static/images/dept.png',
'user': 'static/images/user.png'
}
return data.icon || matcher[data.type]
}
const resolveNameByType = (data) => {
if (data.type === 'role') {
return data.roleName
} else {
return data.userName
}
}
export default {
name: 'index',
components: {
lawsTree2
},
props: ['value'],
data() {
return {
selectNode: {}, // 左侧选中的节点数据
resultNode: {}, // 右侧选中的节点数据
resultNodes: [], // 右侧树数据
editNode: {},
editNodeForForm: {},
editNodeDialogVisible: false
}
},
watch:{
value(newValue, oldValue) {
console.log(newValue)
this.resolveValueToResultNodes(newValue)
}
},
methods: {
resolveValueToResultNodes() {
const value = this.value || []
const result = value.map(item => {
const pId = item.pid || '-1'
const name = resolveNameByType(item)
const userList = []
if (item.tsId) {
userList.push({id: item.tsId, name: item.userName})
}
// 用户的显示需要 用户名+角色
let nameAndRole = name
if (item.type === 'role' && userList && userList.length > 0) {
const userName = userList.map(item => item.name)
nameAndRole = name + ' (' + userName.join(',') + ')'
}
return {
open: true,
id: item.roleCode,
roleCode: item.roleCode,
roleName: item.roleName,
nativeName: name,
name: nameAndRole,
icon: checkNodeIconByType(item),
pId: pId,
wxId: item.id || wxId++,
type: item.type,
userList: userList || []
}
})
this.resultNodes = [rootNode, ...result]
},
},
created() {
this.resolveValueToResultNodes()
}
}
</script>
<style lang="less" scoped>
.tree__wrapper {
display: flex;
justify-content: space-between;
.item {
flex: 1 1 200px;
}
.btn__wrapper {
flex: 0 0 60px;
padding: 10px;
align-self: center;
}
}
</style>
+248
View File
@@ -0,0 +1,248 @@
<template>
<div style="display: inline-block;position: relative;">
<el-button
@click="openNewDialog"
id="question"
class="btn"
icon="icon-separate"
>提交问题</el-button>
<!-- 提交问题 -->
<el-dialog :visible.sync="newDialogVisible" width="600px" destroy-on-close title="提交问题">
<el-form ref="newDialogForm" :model="newDialogForm" :rules="newDialogFormRules" class="label-input-form">
<el-formItem label="问题" prop="content" class="add-form-item" label-width="130px">
<el-input v-model="newDialogForm.content" placeholder="请输入问题" style="width: 6rem"></el-input>
</el-formItem>
<el-formItem label="附件" prop="files" class="add-form-item" label-width="130px">
<el-upload
drag
:on-success="uploadFileSuccess"
:action="uploadFileUrl"
:before-upload="beforeUploadFile"
:show-file-list="true"
:on-format-error="handleFileFormatError"
name="file"
ref="uploadFileNewDialog"
:limit="1"
:on-exceed="onFileExceed"
style="margin-top: 15px;"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">点击或拖拽上传文件</div>
</el-upload>
</el-formItem>
</el-form>
<div slot="footer" class="demo-drawer-footer">
<el-button type="primary" round class="common-button-primary" icon="el-icon-check" @click="confirmNewDialogBtnClick" :loading="submitLoading">确定</el-button>
<el-button round class="common-button-default" icon="el-icon-close" @click="cancelNewDialogBtnClick">取消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: 'PutQuestionButton',
props: {
resId: {
type: String,
required: true
},
resType: {
type: String,
required: true
}
},
data () {
return {
uploadFileUrl: 'api/att/attFile/upload',
newDialogVisible: false,
submitLoading: false,
newDialogForm: {
content: '',
files: ''
},
newDialogFormForReset: {
content: '',
files: ''
},
newDialogFormRules: {
content: [
{required:true,message:'问题不能为空',trigger:'blur'},
{validator: this.verify.remakeY, trigger: 'change'}
],
files: []
}
}
},
methods: {
openNewDialog () {
this.newDialogForm = { ...this.newDialogFormForReset }
this.newDialogVisible = true
},
/**
* 新增弹框 取消按钮
*/
cancelNewDialogBtnClick () {
this.newDialogVisible = false
},
/**
* 新增弹框 提交按钮
*/
// confirmNewDialogBtnClick () {
// const formData = {
// resId: this.resId,
// resType: this.resType,
// qaMsgEOList: [
// {
// qaFile: this.newDialogForm.files,
// qaText: this.newDialogForm.content,
// qaType: 'QUE'
// }
// ]
// }
// this.$http.postData('lawss/sarQaInfo/sendSARQueInfo', formData, {
// _this: this
// }, res => {
// if (res.ok) {
// this.$message({
// message: '操作成功',
// type: 'success'
// })
// console.log('success', res)
// this.newDialogVisible = false
// } else {
//
// throw new Error(res)
// }
// }, err => {
// console.error(err)
// })
// },
confirmNewDialogBtnClick () {
this.$refs['newDialogForm'].validate((valid) => {
if(valid){
const formData = {
resId: this.resId,
resType: this.resType,
qaMsgEOList: [
{
qaFile: this.newDialogForm.files,
qaText: this.newDialogForm.content,
qaType: 'QUE'
}
]
}
this.submitLoading = true
this.$http.postData('lawss/sarQaInfo/sendSARQueInfo', formData, {
_this: this,
submitLoading: 'loading'
}, res => {
if (res.ok) {
console.log('success', res)
this.newDialogVisible = false
this.submitLoading = false
this.$message({
message: '操作成功',
type: 'success'
})
} else {
throw new Error(res)
}
}, err => {
console.error(err)
})
}else{
}
})
},
/**
* 上传文件成功
* @param response
* @param file
*/
uploadFileSuccess (response, file) {
if (response.ok) {
this.$message({
message: response.message,
type: 'success'
})
this.newDialogForm['files'] += response.data.id + ','
} else {
this.$refs.uploadFileNewDialog.clearFiles()
this.$message({
message: response.message,
type: 'warning'
})
}
},
/**
* 上传文件之前的回调
* @param file
* @returns {boolean}
*/
beforeUploadFile (file) {
// var filename = file.name
// var index1 = filename.lastIndexOf('.')
// var index2 = filename.length
// var fileSuffix = filename.substring(index1, index2)
// // const fileSuffix = file.name.split('.')[1] // 后缀名
// // 判断上传文件格式
// // if (fileSuffix === 'pdf' || fileSuffix === 'PDF' || fileSuffix === 'doc' || fileSuffix === 'docx' || fileSuffix === 'ppt' || fileSuffix === 'pptx') {
// if (fileSuffix === '.xlsx' || fileSuffix === '.xls') {
// return true
// } else {
// this.$message.error('文件' + file.name + '格式不正确,请上传xls、xlsx文件')
// return false
// }
// 判断文件上传大小
if (file.size / 1024 / 1024 <= 200) {
return true
} else {
this.$message.error('文件' + file.name + '大小不超过200M')
return false
}
},
// 导入标准文件格式错误执行
handleFileFormatError (file) {
this.$message.error('文件格式不正确')
},
onFileExceed () {
this.$message.error('最多上传一个文件')
}
}
}
</script>
<style lang="less" scoped>
.btn{
//position: absolute;
//top: 10px;
//right: 0;
padding: 0 10px;
height: 30px;
line-height: 30px;
font-size: 14px;
border-radius: 15px;
color: #07C160;
border: 1px solid #07C160;
background: rgba(1, 193, 96, 0.1);
.icon-separate{
display: inline-block;
margin-right: 3px;
width: 16px;
height: 16px;
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: center center;
vertical-align: sub;
background-image: url("~assets/images/shangqi/standardDetails/separate.png");
}
}
</style>
+562
View File
@@ -0,0 +1,562 @@
<!-- 2021-03-03 树组件 -->
<template>
<div class="shang-qi-tree">
<template v-if="drawer">
<el-drawer
:title="title"
:visible.sync="drawerVisible"
:wrapper-closable="false"
:before-close="beforeClose"
@closed="handleClosed">
<div class="demo-drawer-content">
<laws-tree
:zNodes="zNodes"
:treeDivId="treeDivId"
:loading="loading.loadZNodes"
:loading-tips="loadingTips"
:checkIdList="checkIdList"
:check-enable="checkEnable"
:editable="false"
:expand-first="expandFirst"
:only-checked="checkEnable"
:dept-select="!checkEnable"
@treeOnCheck="treeOnCheck"
@treeDblClick="handleDblClick"
v-if="visible"
></laws-tree>
</div>
<div class="demo-drawer-footer" v-if="showFooter && checkEnable">
<el-button
round
class="common-button-primary"
type="primary"
icon="el-icon-check"
@click="handleConfirm"
>确定</el-button
>
<el-button
round
class="common-button-default"
icon="el-icon-close"
@click="handleCancel"
>取消</el-button
>
</div>
</el-drawer>
</template>
<template v-else>
<laws-tree
:zNodes="zNodes"
:treeDivId="treeDivId"
:loading="loading.loadZNodes"
:loading-tips="loadingTips"
:checkIdList="checkIdList"
:check-enable="checkEnable"
:editable="false"
:expand-first="expandFirst"
@treeOnCheck="treeOnCheck"
></laws-tree>
</template>
</div>
</template>
<script>
import {
getDept,
getUserOrgDept
} from 'api'
import {
getRoleAndUserByOrgId,
getRoleByOrgIdOrGroupName as queryRoleListByOrgGroup
} from 'api/process'
export default {
name: 'ShangQiTree',
mixins: [],
components: {},
props: {
// 树结构dom唯一id
treeDivId: {
type: String,
default: () => {
return `${new Date().getTime()}-SQTree`
}
},
// 是否展示全部部门+科室+人员
showAll: {
type: Boolean,
required: true
},
// 是否与Drawer组件一起使用
drawer: {
type: Boolean,
default: true
},
// 机构节点是否禁用checkbox
deptNodeDisabled: {
type: Boolean,
default: false
},
// 是否启用checkBox
checkEnable: {
type: Boolean,
default: true
},
// 当前选中的节点(checkbox回显)
checkIdList: {
type: Array,
default: () => []
},
title: {
type: String,
default: '组织机构'
},
visible: {
type: Boolean,
default: false
},
showFooter: {
type: Boolean,
default: true
},
// 是否选择人员节点
onlyCheckPerson: {
type: Boolean,
default: true
},
// 是否只选择机构节点
onlyCheckOrg: {
type: Boolean,
default: false
},
// 指定机构类型
orgType: {
type: String
},
beforeClose: {
type: Function,
default: (done) => {
done()
}
},
// 最多支持选择数(传-1忽略此参数)
maxSelected: {
type: Number
},
maxSelectedTips: {
type: String
},
// 指定角色组名称(查找指定角色,可选参数部门id)
roleHierarchyName: {
type: String
},
// 指定角色Id查询用户
roleId: {
type: String
},
// 指定部门
orgId: {
type: String
},
// 是否默认展开第一个节点
expandFirst: {
type: Boolean,
default: false
},
// 传roleHierarchyName,orgId时传此参数判断最终要的节点是人还是角色(传USER: 获取人,不传则获取角色)
needType: {
type: String
},
showRole: {
type: Boolean,
default: false
},
// 名字后展示邮箱地址
showEmail: {
type: Boolean,
default: false
},
// 不展示的人员(例如主起草为汪法规,其他起草人不再展示汪法规),格式为逗号拼接id
excludesUser: {
type: [String, Array]
},
// 根据指定条件查询角色分组/人员
queryType: {
type: String,
validator: function (t) {
return t === 'GROUP' || t === 'USER'
},
default: 'USER'
}
},
data () {
return {
drawerVisible: false,
zNodes: [],
loading: {
loadZNodes: false
},
checkedIdList: []
}
},
methods: {
/**
* @description: zNodes初始化
* @date: 2021-03-03 14:38:21
* @auth: chenxiaoxi
*/
zNodesInit() {
if (this.showAll) {
this.loading.loadZNodes = true
this.getAllDept()
.then(deptZNodes => {
this.getAllUser()
.then(userZNodes => {
this.zNodes = [...deptZNodes, ...userZNodes]
setTimeout(() => {
this.loading.loadZNodes = false
}, 100)
})
})
} else {
if (this.onlyCheckOrg) {
this.loading.loadZNodes = true
this.getAllDept({
orgType: this.orgType
}).then(deptZNodes => {
this.zNodes = [...deptZNodes]
setTimeout(() => {
this.loading.loadZNodes = false
}, 100)
})
} else if (this.roleId) {
this.loading.loadZNodes = true
this.getAllDept()
.then(deptNode => {
const zNodes = []
if (this.orgId) {
const orgId = this.orgId.split(',')
deptNode.map(deptItem => {
if (orgId.includes(deptItem.id)) {
zNodes.push(deptItem)
}
})
} else {
zNodes.push(...deptNode)
}
this.getUserByRoleId(zNodes)
})
} else if (this.roleHierarchyName) {
this.getRoleGroupByRoleName()
} else {
this.$message.warning('这种情况前端还没处理,请联系前端开发人员关注SQTree组件')
}
}
},
/**
* @description: 获取全部机构
* @date: 2021-03-03 13:44:26
* @auth: chenxiaoxi
*/
getAllDept(params) {
return new Promise((resolve, reject) => {
getDept(params)
.then(res => {
const { data } = res
// debugger
// 如果指定了部门,则只返回当前部门及下属科室
if (this.orgId) {
const zNodes = []
data.map(item => {
if (item.pId === this.orgId) {
item.name = item.orgName
item.icon = 'static/images/dept.png'
item.chkDisabled = this.deptNodeDisabled
zNodes.push(item)
}
})
resolve(zNodes)
} else {
data.map(item => {
item.name = item.orgName
item.icon = 'static/images/dept.png'
item.chkDisabled = this.deptNodeDisabled
})
resolve(data)
}
})
})
},
/**
* @description: 获取全部人员,人员数据中包含pOrgId,且相同角色只出现一次
* @date: 2021-03-03 13:51:01
* @auth: chenxiaoxi
*/
getAllUser() {
return new Promise((resolve, reject) => {
if (this.showRole) {
getRoleAndUserByOrgId()
.then(res => {
const { data } = res
// 如果指定了部门,则只返回当前部门下或部门科室下的人员
if (this.orgId) {
const zNodes = []
data.map(item => {
if (item.orgId === this.orgId || item.pOrgId === this.orgId) {
const email = item.email && `(${item.email})`
if (this.showRole && item.roleName) {
item.name = item.userName + email + '(' + item.roleName + ')'
} else {
item.name = `${item.userName}${email}`
}
item.icon = 'static/images/user.png'
item.iconSkin = 'org-user'
item.pId = item.orgId
item.id = item.userId
zNodes.push(item)
}
})
resolve(zNodes)
} else {
data.map(item => {
const email = item.email && `(${item.email})`
if (this.showRole && item.roleName) {
item.name = item.userName + email + '(' + item.roleName + ')'
} else {
item.name = `${item.userName}${email}`
}
item.icon = 'static/images/user.png'
item.iconSkin = 'org-user'
item.pId = item.orgId
item.id = item.userId
})
resolve(data)
}
})
} else {
getUserOrgDept()
.then(res => {
const { data } = res
const EXCLUDES_USER = (this.excludesUser && (this.excludesUser instanceof Array ? this.excludesUser : this.excludesUser.split(','))) || []
// 如果指定了部门,则只返回当前部门下或部门科室下的人员
if (this.orgId) {
const zNodes = []
data.map((item, index) => {
if ((item.orgId === this.orgId || item.pOrgId === this.orgId) && (!EXCLUDES_USER.includes(item.id)) || !EXCLUDES_USER.includes(item.userId)) {
item.name = item.userName
item.icon = 'static/images/user.png'
item.iconSkin = 'org-user'
item.pId = item.orgId
item.id = item.userId
const email = item.email && `(${item.email})`
if (this.showEmail && item.email) {
item.name = `${item.userName}${email}`
}
zNodes.push(item)
}
})
resolve(zNodes)
} else {
const zNodes = []
data.map((item, index) => {
item.name = item.userName
item.icon = 'static/images/user.png'
item.iconSkin = 'org-user'
item.pId = item.orgId
item.id = item.userId
if (this.showEmail && item.email) {
item.name = `${item.userName}(${item.email})`
}
if (!EXCLUDES_USER.includes(item.id)) {
zNodes.push(item)
}
})
resolve(zNodes)
}
})
}
})
},
handleClosed() {
this.zNodes = []
this.handleCancel()
},
handleConfirm() {
const idList = []
const checkedList = []
let flag = true
const errPersonNode = []
this.checkedList.map(item => {
if (this.onlyCheckPerson) {
if (item.userId) {
if (item.orgId) {
idList.push(item.id)
checkedList.push(item)
} else {
errPersonNode.push(item.userName)
flag = false
}
}
} else {
idList.push(item.id)
checkedList.push(item)
}
})
if (!flag && this.onlyCheckPerson) {
this.$message.warning(`${errPersonNode.join(',')} 没有上级机构,请重新选择`)
return false
}
if (this.maxSelected && this.maxSelected > -1 && (checkedList.length > this.maxSelected)) {
this.$message.warning(this.maxSelectedTips || `最多支持选择数量: ${this.maxSelected}`)
return false
}
this.$emit('confirm', checkedList, idList)
setTimeout(() => {
this.$emit('update:visible', false)
this.$emit('closed')
}, 100)
},
/**
* 人员单选
**/
handleDblClick(elId, checkNode) {
const checkedList = [checkNode]
const id = checkNode.userId || checkNode.id
const idList = [id]
this.$emit('confirm', checkedList, idList)
setTimeout(() => {
this.$emit('update:visible', false)
this.$emit('closed')
}, 100)
},
handleCancel() {
this.checkedList = []
this.$emit('update:visible', false)
setTimeout(() => {
this.$emit('closed')
}, 100)
},
treeOnCheck(checkedList) {
this.checkedList = checkedList
},
/**
* @description: 根据角色Id获取人员列表(可选参数部门)
* @date: 2021-03-04 10:18:59
* @auth: chenxiaoxi
*/
getUserByRoleId(zNodes) {
this.loading.loadZNodes = true
getRoleAndUserByOrgId({
orgId: this.orgId,
roleId: this.roleId,
roleHierarchyName: this.roleHierarchyName
}).then(res => {
this.loading.loadZNodes = false
const personList = res.data.map(person => {
if (person.orgType === 'DEPART') {
person.pId = person.orgId
} else {
person.pId = person.pOrgId
}
const email = person.email && `(${person.email})`
if (this.showRole) {
const roleName = person.roleName || ''
person.name = person.userName + email + '(' + roleName + ')'
} else {
person.name = `${person.userName}${email}`
}
person.id = person.userId
person.icon = 'static/images/user.png'
person.iconSkin = 'org-user'
return person
})
this.zNodes = [...zNodes, ...personList]
}).catch(e => {
this.loading.loadZNodes = false
})
},
/**
* @description: 根据角色名称查询角色组
* @date: 2021-03-04 11:16:31
* @auth: chenxiaoxi
*/
async getRoleGroupByRoleName() {
this.loading.loadZNodes = true
const params = {
orgId: this.orgId,
roleHierarchyName: this.roleHierarchyName
}
let res, data
if (this.queryType === 'GROUP') {
const fixedRoles = ['法规联络人', '企标备案专家', '标准法规采购员']
if (!fixedRoles.includes(this.roleHierarchyName)) {
params.type = 0
}
res = await queryRoleListByOrgGroup(params)
data = res.data
data.map(role => {
role.icon = 'static/images/user.png'
role.iconSkin = 'org-user'
})
} else {
res = await getRoleAndUserByOrgId(params)
data = res.data
if (this.needType && this.needType === 'USER') {
data.map(role => {
role.name = role.userName
role.id = role.userId
role.icon = 'static/images/user.png'
role.iconSkin = 'org-user'
})
} else {
data.map(role => {
role.name = role.roleName
role.id = role.roleId
role.icon = 'static/images/user.png'
role.iconSkin = 'org-user'
})
}
}
this.zNodes = data
this.loading.loadZNodes = false
}
},
computed: {
loadingTips() {
return `正在加载${this.title}`
}
},
watch: {
visible: {
handler(val) {
if (val) {
this.zNodesInit()
}
this.drawerVisible = val
}
},
drawerVisible: {
handler(val) {
this.$emit('update:visible', val)
}
}
},
mounted () {
this.drawerVisible = this.visible
}
}
</script>
<style lang="less" scoped>
.shang-qi-tree {
}
</style>
-201
View File
@@ -1,201 +0,0 @@
<template>
<div class="select-tree-template">
<el-select
v-model="selectValue"
:clearable="clearable"
:collapse-tags="selectType == 'multiple'"
:multiple="selectType == 'multiple'"
class="vab-tree-select"
value-key="id"
@clear="clearHandle"
@remove-tag="removeTag"
>
<el-option :value="selectKey">
<el-tree
id="treeOption"
ref="treeOption"
:current-node-key="currentNodeKey"
:data="treeOptions"
:default-checked-keys="defaultSelectedKeys"
:default-expanded-keys="defaultSelectedKeys"
:highlight-current="true"
:props="defaultProps"
:show-checkbox="selectType == 'multiple'"
node-key="id"
@check="checkNode"
@node-click="nodeClick"
></el-tree>
</el-option>
</el-select>
</div>
</template>
<script>
export default {
name: 'SelectTreeTemplate',
props: {
/* 树形结构数据 */
treeOptions: {
type: Array,
default: () => {
return []
},
},
/* 单选/多选 */
selectType: {
type: String,
default: () => {
return 'single'
},
},
/* 初始选中值key */
selectedKey: {
type: String,
default: () => {
return ''
},
},
/* 初始选中值name */
selectedValue: {
type: String,
default: () => {
return ''
},
},
/* 可做选择的层级 */
selectLevel: {
type: [String, Number],
default: () => {
return ''
},
},
/* 可清空选项 */
clearable: {
type: Boolean,
default: () => {
return true
},
},
},
data() {
return {
defaultProps: {
children: 'children',
label: 'name',
},
defaultSelectedKeys: [], //初始选中值数组
currentNodeKey: this.selectedKey,
selectValue:
this.selectType == 'multiple'
? this.selectedValue.split(',')
: this.selectedValue, //下拉框选中值label
selectKey:
this.selectType == 'multiple'
? this.selectedKey.split(',')
: this.selectedKey, //下拉框选中值value
}
},
mounted() {
const that = this
this.initTree()
},
methods: {
// 初始化树的值
initTree() {
const that = this
if (that.selectedKey) {
that.defaultSelectedKeys = that.selectedKey.split(',') // 设置默认展开
if (that.selectType == 'single') {
that.$refs.treeOption.setCurrentKey(that.selectedKey) // 设置默认选中
} else {
that.$refs.treeOption.setCheckedKeys(that.defaultSelectedKeys)
}
}
},
// 清除选中
clearHandle() {
const that = this
this.selectValue = ''
this.selectKey = ''
this.defaultSelectedKeys = []
this.currentNodeKey = ''
this.clearSelected()
if (that.selectType == 'single') {
that.$refs.treeOption.setCurrentKey('') // 设置默认选中
} else {
that.$refs.treeOption.setCheckedKeys([])
}
},
/* 清空选中样式 */
clearSelected() {
const allNode = document.querySelectorAll('#treeOption .el-tree-node')
allNode.forEach((element) => element.classList.remove('is-current'))
},
// select多选时移除某项操作
removeTag(val) {
this.$refs.treeOption.setCheckedKeys([])
},
// 点击叶子节点
nodeClick(data, node, el) {
if (data.rank >= this.selectLevel) {
this.selectValue = data.name
this.selectKey = data.id
}
},
// 节点选中操作
checkNode(data, node, el) {
const checkedNodes = this.$refs.treeOption.getCheckedNodes()
const keyArr = []
const valueArr = []
checkedNodes.forEach((item) => {
if (item.rank >= this.selectLevel) {
keyArr.push(item.id)
valueArr.push(item.name)
}
})
this.selectValue = valueArr
this.selectKey = keyArr
},
},
}
</script>
<style lang="scss" scoped>
.el-scrollbar .el-scrollbar__view .el-select-dropdown__item {
height: auto;
max-height: 274px;
padding: 0;
overflow-y: auto;
}
.el-select-dropdown__item.selected {
font-weight: normal;
}
ul li > .el-tree .el-tree-node__content {
height: auto;
padding: 0 20px;
}
.el-tree-node__label {
font-weight: normal;
}
.el-tree > .is-current .el-tree-node__label {
font-weight: 700;
color: #409eff;
}
.el-tree > .is-current .el-tree-node__children .el-tree-node__label {
font-weight: normal;
color: #606266;
}
</style>
<style lang="scss">
/* .vab-tree-select{
.el-tag__close.el-icon-close{
width:0;
overflow:hidden;
}
} */
</style>
-191
View File
@@ -1,191 +0,0 @@
<template>
<div class="content">
<div class="g-container" :style="styleObj">
<div class="g-number">
<vab-count
:start-val="startVal"
:end-val="endVal"
:duration="duration"
:separator="separator"
:prefix="prefix"
:suffix="suffix"
:decimals="decimals"
/>
</div>
<div class="g-contrast">
<div class="g-circle"></div>
<ul class="g-bubbles">
<li v-for="(item, index) in 15" :key="index"></li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'VabCharge',
props: {
styleObj: {
type: Object,
default: () => {
return {}
},
},
startVal: {
type: Number,
default: 0,
},
endVal: {
type: Number,
default: 100,
},
},
data() {
return {
decimals: 2,
prefix: '',
suffix: '%',
separator: ',',
duration: 3000,
}
},
created() {},
mounted() {},
methods: {},
}
</script>
<style lang="scss" scoped>
.content {
position: relative;
display: flex;
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中 */
width: 100%;
background: #000;
.g-number {
position: absolute;
top: 27%;
z-index: 99;
width: 300px;
font-size: 32px;
color: #fff;
text-align: center;
}
.g-container {
position: relative;
width: 300px;
height: 400px;
margin: auto;
}
.g-contrast {
width: 300px;
height: 400px;
overflow: hidden;
background-color: #000;
filter: contrast(15) hue-rotate(0);
animation: hueRotate 10s infinite linear;
}
.g-circle {
position: relative;
box-sizing: border-box;
width: 300px;
height: 300px;
filter: blur(8px);
&::after {
position: absolute;
top: 40%;
left: 50%;
width: 200px;
height: 200px;
content: '';
background-color: #00ff6f;
border-radius: 42% 38% 62% 49% / 45%;
transform: translate(-50%, -50%) rotate(0);
animation: rotate 10s infinite linear;
}
&::before {
position: absolute;
top: 40%;
left: 50%;
z-index: 99;
width: 176px;
height: 176px;
content: '';
background-color: #000;
border-radius: 50%;
transform: translate(-50%, -50%);
}
}
.g-bubbles {
position: absolute;
bottom: 0;
left: 50%;
width: 100px;
height: 40px;
background-color: #00ff6f;
filter: blur(5px);
border-radius: 100px 100px 0 0;
transform: translate(-50%, 0);
}
li {
position: absolute;
background: #00ff6f;
border-radius: 50%;
}
@for $i from 0 through 15 {
li:nth-child(#{$i}) {
$width: 15 + random(15) + px;
top: 50%;
left: 15 + random(70) + px;
width: $width;
height: $width;
transform: translate(-50%, -50%);
animation: moveToTop
#{random(6) +
3}s
ease-in-out -#{random(5000) /
1000}s
infinite;
}
}
@keyframes rotate {
50% {
border-radius: 45% / 42% 38% 58% 49%;
}
100% {
transform: translate(-50%, -50%) rotate(720deg);
}
}
@keyframes moveToTop {
90% {
opacity: 1;
}
100% {
opacity: 0.1;
transform: translate(-50%, -180px);
}
}
@keyframes hueRotate {
100% {
filter: contrast(15) hue-rotate(360deg);
}
}
}
</style>
-313
View File
@@ -1,313 +0,0 @@
<template>
<div class="card" :style="styleObj">
<div class="card-borders">
<div class="border-top"></div>
<div class="border-right"></div>
<div class="border-bottom"></div>
<div class="border-left"></div>
</div>
<div class="card-content">
<el-image :src="avatar" class="avatar"></el-image>
<div class="username">{{ username }}</div>
<div class="social-icons">
<a
v-for="(item, index) in iconArray"
:key="index"
class="social-icon"
:href="item.url"
target="_blank"
>
<vab-icon :icon="['fas', item.icon]" />
</a>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'VabProfile',
props: {
styleObj: {
type: Object,
default: () => {
return {}
},
},
username: {
type: String,
default: '',
},
avatar: {
type: String,
default: '',
},
iconArray: {
type: Array,
default: () => {
return [
{ icon: 'bell', url: '' },
{ icon: 'bookmark', url: '' },
{ icon: 'cloud-sun', url: '' },
]
},
},
},
data() {
return {}
},
created() {},
mounted() {},
methods: {},
}
</script>
<style lang="scss" scoped>
.card {
--card-bg-color: hsl(240, 31%, 25%);
--card-bg-color-transparent: hsla(240, 31%, 25%, 0.7);
position: relative;
width: 100%;
height: 100%;
.card-borders {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
.border-top {
position: absolute;
top: 0;
width: 100%;
height: 2px;
background: var(--card-bg-color);
transform: translateX(-100%);
animation: slide-in-horizontal 0.8s cubic-bezier(0.645, 0.045, 0.355, 1)
forwards;
}
.border-right {
position: absolute;
right: 0;
width: 2px;
height: 100%;
background: var(--card-bg-color);
transform: translateY(100%);
animation: slide-in-vertical 0.8s cubic-bezier(0.645, 0.045, 0.355, 1)
forwards;
}
.border-bottom {
position: absolute;
bottom: 0;
width: 100%;
height: 2px;
background: var(--card-bg-color);
transform: translateX(100%);
animation: slide-in-horizontal-reverse 0.8s
cubic-bezier(0.645, 0.045, 0.355, 1) forwards;
}
.border-left {
position: absolute;
top: 0;
width: 2px;
height: 100%;
background: var(--card-bg-color);
transform: translateY(-100%);
animation: slide-in-vertical-reverse 0.8s
cubic-bezier(0.645, 0.045, 0.355, 1) forwards;
}
}
.card-content {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
padding: 40px 0 40px 0;
background: var(--card-bg-color-transparent);
opacity: 0;
transform: scale(0.6);
animation: bump-in 0.5s 0.8s forwards;
.avatar {
width: 80px;
height: 80px;
border: 1px solid $base-color-white;
border-radius: 50%;
opacity: 0;
transform: scale(0.6);
animation: bump-in 0.5s 1s forwards;
}
.username {
position: relative;
margin-top: 20px;
margin-bottom: 20px;
font-size: 26px;
color: transparent;
letter-spacing: 2px;
animation: fill-text-white 1.2s 2s forwards;
&::before {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
color: black;
content: '';
background: #35b9f1;
transform: scaleX(0);
transform-origin: left;
animation: slide-in-out 1.2s 1.2s cubic-bezier(0.75, 0, 0, 1) forwards;
}
}
.social-icons {
display: flex;
.social-icon {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 2.5em;
height: 2.5em;
margin: 0 15px;
color: white;
text-decoration: none;
border-radius: 50%;
@for $i from 1 through 3 {
&:nth-child(#{$i}) {
&::before {
animation-delay: 2s + 0.1s * $i;
}
&::after {
animation-delay: 2.1s + 0.1s * $i;
}
svg {
animation-delay: 2.2s + 0.1s * $i;
}
}
}
&::before,
&::after {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
content: '';
border-radius: inherit;
transform: scale(0);
}
&::before {
background: #f7f1e3;
animation: scale-in 0.5s cubic-bezier(0.75, 0, 0, 1) forwards;
}
&::after {
background: #2c3e50;
animation: scale-in 0.5s cubic-bezier(0.75, 0, 0, 1) forwards;
}
svg {
z-index: 99;
transform: scale(0);
animation: scale-in 0.5s cubic-bezier(0.75, 0, 0, 1) forwards;
}
}
}
}
}
@keyframes bump-in {
50% {
transform: scale(1.05);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes slide-in-horizontal {
50% {
transform: translateX(0);
}
to {
transform: translateX(100%);
}
}
@keyframes slide-in-horizontal-reverse {
50% {
transform: translateX(0);
}
to {
transform: translateX(-100%);
}
}
@keyframes slide-in-vertical {
50% {
transform: translateY(0);
}
to {
transform: translateY(-100%);
}
}
@keyframes slide-in-vertical-reverse {
50% {
transform: translateY(0);
}
to {
transform: translateY(100%);
}
}
@keyframes slide-in-out {
50% {
transform: scaleX(1);
transform-origin: left;
}
50.1% {
transform-origin: right;
}
100% {
transform: scaleX(0);
transform-origin: right;
}
}
@keyframes fill-text-white {
to {
color: white;
}
}
@keyframes scale-in {
to {
transform: scale(1);
}
}
</style>
-82
View File
@@ -1,82 +0,0 @@
<template>
<div class="content" :style="styleObj">
<div v-for="(item, index) in 200" :key="index" class="snow"></div>
</div>
</template>
<script>
export default {
name: 'VabSnow',
props: {
styleObj: {
type: Object,
default: () => {
return {}
},
},
},
data() {
return {}
},
created() {},
mounted() {},
methods: {},
}
</script>
<style lang="scss" scoped>
.content {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
background: radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%);
filter: drop-shadow(0 0 10px white);
}
@function random_range($min, $max) {
$rand: random();
$random_range: $min + floor($rand * (($max - $min) + 1));
@return $random_range;
}
.snow {
$total: 200;
position: absolute;
width: 10px;
height: 10px;
background: white;
border-radius: 50%;
@for $i from 1 through $total {
$random-x: random(1000000) * 0.0001vw;
$random-offset: random_range(-100000, 100000) * 0.0001vw;
$random-x-end: $random-x + $random-offset;
$random-x-end-yoyo: $random-x + ($random-offset / 2);
$random-yoyo-time: random_range(30000, 80000) / 100000;
$random-yoyo-y: $random-yoyo-time * 100vh;
$random-scale: random(10000) * 0.0001;
$fall-duration: random_range(10, 30) * 1s;
$fall-delay: random(30) * -1s;
&:nth-child(#{$i}) {
opacity: random(10000) * 0.0001;
transform: translate($random-x, -10px) scale($random-scale);
animation: fall-#{$i} $fall-duration $fall-delay linear infinite;
}
@keyframes fall-#{$i} {
#{percentage($random-yoyo-time)} {
transform: translate($random-x-end, $random-yoyo-y)
scale($random-scale);
}
to {
transform: translate($random-x-end-yoyo, 100vh) scale($random-scale);
}
}
}
}
</style>
-255
View File
@@ -1,255 +0,0 @@
<template>
<el-dialog
:before-close="handleClose"
:close-on-click-modal="false"
:title="title"
:visible.sync="dialogFormVisible"
width="909px"
>
<div class="upload">
<el-alert
:closable="false"
:title="`支持jpg、jpeg、png格式,单次可最多选择${limit}张图片,每张不可大于${size}M,如果大于${size}M会自动为您过滤`"
type="info"
></el-alert>
<br />
<el-upload
ref="upload"
:action="action"
:auto-upload="false"
:close-on-click-modal="false"
:data="data"
:file-list="fileList"
:headers="headers"
:limit="limit"
:multiple="true"
:name="name"
:on-change="handleChange"
:on-error="handleError"
:on-exceed="handleExceed"
:on-preview="handlePreview"
:on-progress="handleProgress"
:on-remove="handleRemove"
:on-success="handleSuccess"
accept="image/png, image/jpeg"
class="upload-content"
list-type="picture-card"
>
<i slot="trigger" class="el-icon-plus"></i>
<el-dialog
:visible.sync="dialogVisible"
append-to-body
title="查看大图"
>
<div>
<img :src="dialogImageUrl" alt="" width="100%" />
</div>
</el-dialog>
</el-upload>
</div>
<div
slot="footer"
class="dialog-footer"
style="position: relative; padding-right: 15px; text-align: right"
>
<div
v-if="show"
style="position: absolute; top: 10px; left: 15px; color: #999"
>
正在上传中... 当前上传成功数:{{ imgSuccessNum }} 当前上传失败数:{{
imgErrorNum
}}
</div>
<el-button type="primary" @click="handleClose">关闭</el-button>
<el-button
:loading="loading"
size="small"
style="margin-left: 10px"
type="success"
@click="submitUpload"
>
开始上传
</el-button>
</div>
</el-dialog>
</template>
<script>
import { baseURL, tokenName } from '@/config'
export default {
name: 'VabUpload',
props: {
url: {
type: String,
default: '/upload',
required: true,
},
name: {
type: String,
default: 'file',
required: true,
},
limit: {
type: Number,
default: 50,
required: true,
},
size: {
type: Number,
default: 1,
required: true,
},
},
data() {
return {
show: false,
loading: false,
dialogVisible: false,
dialogImageUrl: '',
action: 'https://vab-unicloud-3a9da9.service.tcloudbase.com/upload',
headers: {},
fileList: [],
picture: 'picture',
imgNum: 0,
imgSuccessNum: 0,
imgErrorNum: 0,
typeList: null,
title: '上传',
dialogFormVisible: false,
data: {},
}
},
computed: {
percentage() {
if (this.allImgNum == 0) return 0
return this.$baseLodash.round(this.imgNum / this.allImgNum, 2) * 100
},
},
methods: {
submitUpload() {
this.$refs.upload.submit()
},
handleProgress(event, file, fileList) {
this.loading = true
this.show = true
},
handleChange(file, fileList) {
if (file.size > 1048576 * this.size) {
fileList.map((item, index) => {
if (item === file) {
fileList.splice(index, 1)
}
})
this.fileList = fileList
} else {
this.allImgNum = fileList.length
}
},
handleSuccess(response, file, fileList) {
this.imgNum = this.imgNum + 1
this.imgSuccessNum = this.imgSuccessNum + 1
if (fileList.length === this.imgNum) {
setTimeout(() => {
this.$baseMessage(
`上传完成! 共上传${fileList.length}张图片`,
'success'
)
}, 1000)
}
setTimeout(() => {
this.loading = false
this.show = false
}, 1000)
},
handleError(err, file, fileList) {
this.imgNum = this.imgNum + 1
this.imgErrorNum = this.imgErrorNum + 1
this.$baseMessage(
`文件[${file.raw.name}]上传失败,文件大小为${this.$baseLodash.round(
file.raw.size / 1024,
0
)}KB`,
'error'
)
setTimeout(() => {
this.loading = false
this.show = false
}, 1000)
},
handleRemove(file, fileList) {
this.imgNum = this.imgNum - 1
this.allNum = this.allNum - 1
},
handlePreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
handleExceed(files, fileList) {
this.$baseMessage(
`当前限制选择 ${this.limit} 个文件,本次选择了
${files.length}
个文件`,
'error'
)
},
handleShow(data) {
this.title = '上传'
this.data = data
this.dialogFormVisible = true
},
handleClose() {
this.fileList = []
this.picture = 'picture'
this.allImgNum = 0
this.imgNum = 0
this.imgSuccessNum = 0
this.imgErrorNum = 0
/* if ("development" === process.env.NODE_ENV) {
this.api = process.env.VUE_APP_BASE_API;
} else {
this.api = `${window.location.protocol}//${window.location.host}`;
}
this.action = this.api + this.url; */
this.dialogFormVisible = false
},
},
}
</script>
<style lang="scss" scoped>
.upload {
height: 500px;
.upload-content {
.el-upload__tip {
display: block;
height: 30px;
line-height: 30px;
}
::v-deep {
.el-upload--picture-card {
width: 128px;
height: 128px;
margin: 3px 8px 8px 8px;
border: 2px dashed #c0ccda;
}
.el-upload-list--picture {
margin-bottom: 20px;
}
.el-upload-list--picture-card {
.el-upload-list__item {
width: 128px;
height: 128px;
margin: 3px 8px 8px 8px;
}
}
}
}
}
</style>
File diff suppressed because it is too large Load Diff
+55
View File
@@ -0,0 +1,55 @@
# 组件相关
## twoOption
搜索字段
```
{
label: '计划状态',
value: 'access_content',
type: 'INPUT', // 搜索字段的类型
disabled: false,
selVal: '' // 特殊组件会使用到
}
```
### type
- SEL_OPTION
- SEL_OPTS
- DATE_PIC_OPTS
- INPUT
### selVal
#### SEL_OPTION
- ORGLIST
- USERLIST
- ROLELIST
#### SEL_OPTS
- ORGLIST
- USERLIST
- ROLELIST
- SVPPS
## threeOptions
搜索字段对应的选项
```javascript
[
{
label: '未发布',
value: '1'
},
{
label: '已发布',
value: '2'
},
]
```
+92
View File
@@ -0,0 +1,92 @@
<!-- 回到顶部 -->
<template>
<div class="back-top" v-if="visibleBackTop">
<i class="el-icon-arrow-up" @click="scrollTop" />
</div>
</template>
<script>
export default {
name: 'back-top',
data () {
return {
visibleBackTop: false,
scrollDom: null
}
},
methods: {
// 滚动监听
handleScroll () {
const scrollTop = this.windowScroll ? document.documentElement.scrollTop : this.scrollDom.scrollTop
if (scrollTop > 200) {
this.visibleBackTop = true
} else {
this.visibleBackTop = false
}
},
// 回到顶部
scrollTop () {
this.scrollAnimation(this.windowScroll ? document.documentElement.scrollTop : this.scrollDom.scrollTop, 0)
},
scrollAnimation (currentY, targetY) {
// 计算需要移动的距离
let needScrollTop = targetY - currentY
let _currentY = currentY
setTimeout(() => {
// 一次调用滑动帧数,每次调用会不一样
const dist = Math.ceil(needScrollTop / 10)
_currentY += dist
this.scrollDom.scrollTo(_currentY, currentY)
// 如果移动幅度小于十个像素,直接移动,否则递归调用,实现动画效果
if (needScrollTop > 10 || needScrollTop < -10) {
this.scrollAnimation(_currentY, targetY)
} else {
this.scrollDom.scrollTo(_currentY, targetY)
}
}, 1)
}
},
components: {},
props: {
scrollBind: {
type: String,
required: true
},
// 全屏滚动监听
windowScroll: {
type: Boolean,
default: false
}
},
computed: {},
watch: {},
mounted () {
if (!this.windowScroll) {
this.scrollDom = document.getElementById(this.scrollBind)
} else {
this.scrollDom = window
}
this.scrollDom.addEventListener('scroll', this.handleScroll)
},
unmounted () {
this.scrollDom.removeEventListener('scroll', this.handleScroll)
}
}
</script>
<style lang="less">
.back-top{
position: fixed;
bottom: 20px;
right: 20px;
text-align: center;
font-size: 35px;
background: #666;
color: #FFF;
z-index: 100;
&:hover{
cursor: pointer;
background: #4C4C4C;
}
}
</style>
+159
View File
@@ -0,0 +1,159 @@
<!-- header头部 面包屑退出 -->
<template>
<div class="com-header">
<div class="toggle-btn iconfont" style="color: #333333;" @click="handleToggleSideBar">&#xe647;</div>
<div class="header-content-wrap">
<div class="header-left">
<!--面包屑-->
<el-breadcrumb separator="/">
<el-breadcrumb-item
v-for="(item, index) in routerList"
:key="index"
>
{{ item.meta.title }}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<!-- header头部 右侧内容 当前登录人和退出-->
<div class="header-right">
<div class="user-info">
<el-dropdown
trigger="click"
@command="handleCommand"
>
<div class="user-box">
<img :src="userAvator" v-if="$store.getters.userInfo.avator">
<span class="iconfont" v-else style="color: #333333;">&#xe69b;</span>
<span>您好{{ $store.getters.userInfo.uName }}</span>
<i class="el-icon-arrow-down"/>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="loginOut">退出</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapMutations, mapGetters } from 'vuex'
export default {
name: 'ComHeader',
data () {
return {
routerList: [] // 面包屑数组
}
},
created () {
// 渲染面包屑数组
this.routerList = this.$route.matched
},
computed: {
// 获取用户头像
userAvator () {
return this.$store.getters.userInfo.avator || require('@/assets/images/avator_default.png')
},
...mapGetters(['isCollapse'])
},
watch: {
// 监听路由 重新渲染面包屑
$route () {
this.routerList = this.$route.matched
}
},
methods: {
// 点击下拉选项事件
handleCommand (command) {
// 退出登录
if (command === 'loginOut') {
this.$confirm('您确认要退出吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
confirmButtonClass: 'common-button-primary',
roundButton: true
}).then(() => {
this.$store.commit('setTypeFlag', 'loginOut')
this.$http.get('logout', {}, {
_this: this
}, res => {
this.$store.dispatch('logout')
this.$router.push('/login')
}, e => {})
}).catch(() => {
})
}
},
handleToggleSideBar() {
this.toggleSideBar(!this.isCollapse)
},
...mapMutations(['toggleSideBar'])
}
}
</script>
<style lang="less" scoped>
.com-header{
padding: 0 10px;
height: 50px;
background: #ffffff;
border-bottom: 1px solid #e5e5e5;
display: flex;
align-items: center;
.toggle-btn {
margin-right: 8px;
font-size: 28px;
&:hover {
cursor: pointer;
color: #888;
}
}
.header-content-wrap {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
}
.header-right {
display: flex;
align-items: center;
.el-dropdown{
.user-box {
display: flex;
align-items: center;
.iconfont {
font-size: 22px;
margin-right: 5px;
}
& > img{
width: 25px;
}
}
.user-box:hover{
cursor: pointer;
}
.el-dropdown-menu {
outline: none;
border: none;
}
}
.search {
font-size: 20px;
color: rgba(165, 165, 165, 1);
position: relative;
&:hover {
cursor: pointer;
color: #666;
}
}
.line {
width: 1px;
height: 18px;
background: #D1D1D1;
margin: 0 12px;
}
}
}
</style>
+118
View File
@@ -0,0 +1,118 @@
<!--根据部门查询角色信息-->
<template>
<el-drawer
title="选择角色"
:visible.sync="visible"
:wrapper-closable="false"
size="350px"
append-to-body
destroy-on-close
@close="handleTreeDrawerCancel"
>
<div class="demo-drawer-content">
<laws-tree
ref="deptRoleTree"
:loading="loading"
:zNodes="zNodes"
:check-enable="checkEnable"
treeDivId="deptRoleTree"
:editable="false"
expandFirst
:onlyChecked="checkEnable"
:checkIdList="checkIdList"
:chkboxType="{ 'Y': '', 'N': '' }"
@treeOnCheck="handleTreeOnCheck"
@treeDblClick="handleTreeDblClick"
></laws-tree>
</div>
<div v-if="checkEnable" class="demo-drawer-footer">
<el-button
round
class="common-button-primary"
icon="el-icon-check"
type="primary"
:loading="sumbitLoading"
@click="handleTreeDrawerConfirm">确定
</el-button>
<el-button
round
class="common-button-default"
icon="el-icon-close"
@click="handleTreeDrawerCancel">取消</el-button>
</div>
</el-drawer>
</template>
<script>
export default {
name: 'DeptRoleTree',
props: {
isShow: {
type: Boolean,
default: false
},
// 树结构数据
zNodes: {
type: Array,
default: () => {
return []
}
},
// 回显数据
checkIdList: {
type: Array,
default: () => {
return []
}
},
// 单选多选
checkEnable: {
type: Boolean,
default: true
},
// 确定事件loading
sumbitLoading: {
type: Boolean,
default: false
},
loading: {
type: Boolean,
default: false
}
},
data () {
return {
visible: false,
checkedListTwo: []
}
},
methods: {
handleTreeOnCheck (checkedList) {
this.checkedListTwo = checkedList
},
// 人员多选确定事件
handleTreeDrawerConfirm() {
this.$emit('confirm', this.checkedListTwo)
this.visible = false
},
// 单选双击事件
handleTreeDblClick (treeId, treeNode) {
this.$emit('dblClick', treeNode)
this.visible = false
},
// 抽屉关闭事件
handleTreeDrawerCancel () {
this.$emit('cancle')
this.visible = false
this.checkedListTwo = []
}
},
watch: {
isShow (val) {
this.visible = val
},
visible (val) {
this.$emit('update:isShow', val)
}
}
}
</script>
+511
View File
@@ -0,0 +1,511 @@
<!-- 流程组织机构树 -->
<template>
<div class="dept-tree">
<laws-tree
ref="deptTree"
:treeDivId="treeDivId"
:zNodes="zNodes"
:expandAll="expandAll"
:editable="editable"
:deptSelect="deptSelect"
:pIdCheck="pIdCheck"
:checkEnable="checkEnable"
:loading="loading.treeLoading"
:onlyChecked="onlyChecked"
:chkboxType="chkboxType"
:checkIdList="checkIdList"
initNotCheck
@treeClick="(treeId, treeNode) => treeClick(treeId, treeNode)"
@treeOnExpand="(treeId, treeNode) => treeOnExpand(treeId, treeNode)"
@treeDblClick="(treeId, treeNode) => treeDblClick(treeId, treeNode)"
@treeReady="treeReady"
@treeOnCheck="(checkedList) => treeOnCheck(checkedList)"
></laws-tree>
</div>
</template>
<script>
import eventHub from '@/common/eventHub'
export default {
name: 'deptTree',
data () {
return {
dept: [], // 部门节点
deptUser: [], // 部门人员节点
projectManagerzNodes: [],
loading: {
treeLoading: false
}
}
},
methods: {
// 节点点击
treeClick (treeId, treeNode) {
this.$emit('treeClick', treeId, treeNode)
},
// 节点双击
treeDblClick (treeId, treeNode) {
this.$emit('treeDblClick', treeId, treeNode)
},
// 节点展开
treeOnExpand (treeId, treeNode) {
// this.projectManagerClick(treeNode.id, this.projectManagerzNodes)
// this.$emit('treeOnExpand', treeId, treeNode)
},
// 首次加载完成
treeReady () {
this.$emit('treeReady')
},
// 节点重新加载
treeReload () {
this.$refs.deptTree.lawsTreeInit()
},
// 选择节点复选框事件
treeOnCheck (checkedList) {
const personCheckedNameList = []
const personCheckedIdList = []
checkedList.map(item => {
if (item.orgName) {
personCheckedNameList.push(item.name)
personCheckedIdList.push(item.id)
}
})
const personCheckedId = personCheckedIdList.join(',')
const personCheckedName = personCheckedNameList.join(',')
this.$emit('treeOnCheck', checkedList)
this.$emit('personCheck', personCheckedId, personCheckedName)
},
// 回显选中checked节点
checkedNode (checkedNodes) {
this.$refs.deptTree.checkedNode(checkedNodes)
},
/**
* @description: 获取组织到部门
* @author: chenxiaoxi
* @date: 2018/10/11 16:29:37
*/
getDept () {
this.loading.treeLoading = true
return new Promise((resolve, reject) => {
let url = this.allDept ? 'sys/org/getTree' : 'sys/org/getIdsByorgType'
this.$http.get('sys/org/getTree', {
orgType: this.allDept ? '' : 'DEPART'
}, {
_this: this
}, res => {
if (res.ok) {
let zNodesDept = []
res.data.map((item, i) => {
if (this.orgType) {
if (item.orgType === this.orgType) {
let zObj = {}
// 该节点为机构
zObj.name = item.orgName
zObj.icon = 'static/images/dept.png'
// zObj.isParent = true
zObj.shotName = item.shotName
zObj.remarks = item.remarks
zObj.id = item.id
zObj.pId = item.pId
zObj.orgType = item.orgType
zNodesDept.push(zObj)
}
} else {
let zObj = {}
// 该节点为机构
zObj.name = item.orgName
zObj.icon = 'static/images/dept.png'
// zObj.isParent = true
zObj.shotName = item.shotName
zObj.remarks = item.remarks
zObj.id = item.id
zObj.pId = item.pId
zObj.orgType = item.orgType
zNodesDept[i] = zObj
}
})
this.dept = zNodesDept
resolve(res.data)
}
}, e => {
reject(e)
})
})
},
/**
* @description: 获取所有人员
* @author: chenxiaoxi
* @date: 2018/10/11 16:57:33
*/
getUser (treeNodeList) {
return new Promise((resolve, reject) => {
this.$http.get('sys/user', {
pageNo: 1,
isStandard: 'true',
processFlag: '1',
pageSize: 99999
}, {
_this: this
}, res => {
if (res.ok) {
const EXCLUDES_USER = (this.excludesUser && (this.excludesUser instanceof Array ? this.excludesUser : this.excludesUser.split(','))) || []
for (let i = 0; i < res.data.list.length; i++) {
if (!EXCLUDES_USER.includes(res.data.list[i].usid)) {
let obj = {}
for (let key in res.data.list[i]) {
if (key === 'usid') {
obj.id = res.data.list[i][key]
} else if (key === 'orgId') {
obj.pId = res.data.list[i][key]
} else {
obj[key] = res.data.list[i][key]
}
}
obj.userId = res.data.list[i].userId || res.data.list[i].usid
treeNodeList.push(obj)
}
}
// 获取组织与人员完毕,开始组装树结构
let zNodes = []
for (let i = 0; i < treeNodeList.length; i++) {
let zObj = {}
zObj.id = treeNodeList[i].id
zObj.pId = treeNodeList[i].pId
zObj.orgType = treeNodeList[i].orgType
// 该节点为人员
if (treeNodeList[i].uname !== undefined) {
if (treeNodeList[i].email) {
if (treeNodeList[i].roleName) {
zObj.name = `${treeNodeList[i].uname}(${treeNodeList[i].email})(${treeNodeList[i].roleName})`
zObj.oldname = `${treeNodeList[i].uname}(${treeNodeList[i].email})(${treeNodeList[i].roleName})`
} else {
zObj.name = `${treeNodeList[i].uname}(${treeNodeList[i].email})`
zObj.oldname = `${treeNodeList[i].uname}(${treeNodeList[i].email})`
}
} else {
if (treeNodeList[i].roleName) {
zObj.name = `${treeNodeList[i].uname}(${treeNodeList[i].roleName})`
} else {
zObj.name = `${treeNodeList[i].uname}`
}
}
zObj.userName = treeNodeList[i].uname
zObj.icon = 'static/images/user.png'
zObj.isParent = false
zObj.orgName = treeNodeList[i].orgName
zObj.pOrgId = treeNodeList[i].pOrgId
zObj.pOrgName = treeNodeList[i].pOrgName
zObj.iconSkin = 'org-user'
zObj.userId = treeNodeList[i].userId || treeNodeList[i].usid
} else {
// 该节点为机构
zObj.name = treeNodeList[i].orgName
zObj.icon = 'static/images/dept.png'
zObj.isParent = true
zObj.isChecked = true
}
zObj.shotName = treeNodeList[i].shotName
zObj.remarks = treeNodeList[i].remarks
if (zObj.pId === null && !zObj.isParent) {
zObj.pId = ''
zObj.orgName = '未分配人员'
}
zNodes[i] = zObj
}
zNodes.push({
id: '',
pId: null,
name: '未分配人员',
isParent: true,
icon: 'static/images/dept.png'
})
this.deptUser = zNodes
this.loading.treeLoading = false
eventHub.$emit('deptUser', this.deptUser)
}
resolve()
}, e => {
reject(e)
})
})
},
/**
* @description: 选中节点移除
* @author: chenxiaoxi
* @date: 2018/10/29 14:42:02
*/
removeNode (treeNode) {
this.$refs.deptTree.removeNode(treeNode)
},
/**
* @description: 节点添加
* @author: chenxiaoxi
* @date: 2018/10/29 14:53:24
*/
addNode (treeNode) {
this.$refs.deptTree.addNode(treeNode)
},
/**
* @description: 节点取消选中
* @author: chenxiaoxi
* @date: 2018/10/29 16:09:11
*/
cancelSelectedNode (treeNode) {
if (treeNode !== '' && treeNode !== undefined) {
this.$refs.deptTree.cancelSelectedNode(treeNode)
} else {
this.$refs.deptTree.cancelSelectedNode()
}
},
/**
* @description: 节点选中
* @author: chenxiaoxi
* @date: 2018/10/29 16:14:23
*/
selectNode (treeNode) {
if (treeNode !== '' && treeNode !== undefined) {
this.$refs.deptTree.selectNode(treeNode)
}
},
/**
* @description: 获取选中节点
* @author: chenxiaoxi
* @date: 2018/10/29 16:14:23
*/
getSelectNode (idList) {
return this.$refs.deptTree.getSelectNode(idList)
},
/**
* @description: 保存打开的节点
* @author: chenxiaoxi
* @date: 2018/11/23 16:37:01
*/
setOpenNodes () {
this.$refs.deptTree.setOpenNodes()
},
/**
* @description: 清空过滤输入框
* @author: chenxiaoxi
* @date: 2018/11/23 16:52:10
*/
clearSearch () {
this.$refs.deptTree.clearSearch()
},
/**
* @author liruohao
* @date 2019/4/24
* @Description: 获取选中的部门下子子部门
*/
getDeptChild (list) {
this.$http.get('sys/org/getChildDept', {
orgId: list[0]
}, {
_this: this
}, res => {
if (res.ok) {
// 获取组织与人员完毕,开始组装树结构
let zNodes = []
let treeNodeList = res.data
for (let i = 0; i < treeNodeList.length; i++) {
let zObj = {}
zObj.id = treeNodeList[i].id
zObj.pId = treeNodeList[i].pId
// 该节点为机构
zObj.name = treeNodeList[i].orgName
zObj.icon = 'static/images/dept.png'
zObj.isParent = true
zObj.shotName = treeNodeList[i].shotName
zObj.remarks = treeNodeList[i].remarks
zNodes[i] = zObj
}
this.projectManagerClick(list[0], zNodes)
}
}, e => {
})
},
/**
* @author liruohao
* @date 2019/4/23
* @Description: 根据部门查询项目经理 责任工程师
*/
projectManagerClick (id, treeNodeList) {
this.$http.get('sys/org/getTreeByRoleAndOrgId1', {
roleName: this.department[1],
orgId: id,
processFlag: '1'
}, {
_this: this
}, res => {
if (res.ok) {
if (res.data.list.length !== 0) {
for (let i = 0; i < res.data.list.length; i++) {
let obj = {}
for (let key in res.data.list[i]) {
if (key === 'usId') {
obj.id = res.data.list[i][key]
} else if (key === 'userName') {
obj.name = res.data.list[i][key]
} else {
obj.icon = 'static/images/user.png'
obj.isParent = false
obj[key] = res.data.list[i][key]
}
}
treeNodeList.push(obj)
}
this.projectManagerzNodes = treeNodeList
}
}
}, e => {
})
}
},
components: {},
props: {
// 是否显示组织下的用户
showUser: {
type: Boolean,
default: false
},
// 是否禁用
disabled: {
type: Boolean,
default: false
},
// 部门节点
zNodesDept: {
type: Array
},
// 部门人员节点
zNodesDeptUser: {
type: Array
},
// 是否可进行操作
editable: {
type: Boolean,
default: true
},
// 部门是否可以被选择
deptSelect: {
type: Boolean,
default: false
},
// 树实例Id
treeDivId: {
type: String
},
// 是否获取所有组织
allDept: {
type: Boolean,
default: false
},
// 是否根据责任部门查找经理
department: {
type: Array
},
// 需要回显的节点
idList: {
type: Array,
required: false
},
// 回显的部门节点
deptList: {
type: Array
},
// 是否展开全部
expandAll: {
type: Boolean,
default: false
},
// 不选中根节点
pIdCheck: {
type: Boolean,
default: false
},
// 是否开启复选框
checkEnable: {
type: Boolean,
default: false
},
// 只能checkbox选中,不能点击选中节点
onlyChecked: {
type: Boolean,
default: false
},
chkboxType: {
type: Object,
default: () => {
return {'Y': 'ps', 'N': 'ps'}
}
},
// checkbox需要选中的节点
checkIdList: {
type: Array,
default: () => {
return []
}
},
orgType: {
type: String
},
// 不展示的人员(例如主起草为汪法规,其他起草人不再展示汪法规),格式为逗号拼接id
excludesUser: {
type: [String, Array]
}
},
computed: {
// 节点(给lawsTree传的节点,根据展示的类型传不同的值)
zNodes () {
return this.showUser ? (this.zNodesDeptUser || this.deptUser) : (this.projectManagerzNodes.length === 0 ? (this.zNodesDept || this.dept) : this.projectManagerzNodes)
}
},
watch: {
zNodes (val) {
this.$nextTick(() => {
if (this.idList && this.idList.length) {
let deptUser = this.$refs.deptTree.getSelectNode(this.idList)
this.$emit('selectNodeUser', deptUser)
}
})
},
deptList (val) {
if (val.length) {
let zNodes = this.showUser ? (this.zNodesDeptUser || this.deptUser) : (this.zNodesDept || this.dept)
for (let i = 0; i < zNodes.length; i++) {
val.map((displayNode) => {
if (zNodes[i].id === displayNode.id) {
zNodes.splice(i, 1)
}
})
}
}
}
},
mounted () {
if (this.department) {
this.getDeptChild(this.department)
} else {
this.getDept().then(res => {
this.getUser(res)
}, e => {})
}
}
}
</script>
<style lang="less">
.dept-tree{
height: 100%;
flex: auto;
display: flex;
flex-direction: column;
}
</style>
+298
View File
@@ -0,0 +1,298 @@
<!--生成企标编号组件-->
<template>
<div>
<el-drawer
:visible.sync="visibleShow"
:title="title"
@close="close"
size="500px"
>
<div class="demo-drawer-content">
<el-form
ref="generationNumberForm"
:model="generationNumberForm"
:rules="generationNumberFormRules"
class="label-input-form"
label-width="150px"
>
<el-form-item label="标准代号" prop="standCode" class="add-form-item form-item-disabled">
<el-input
v-model="generationNumberForm.standCode"
placeholder="请输入标准代号"
disabled
></el-input>
</el-form-item>
<el-form-item label="标准属性" prop="standAttribute" class="add-form-item">
<el-select
filterable
v-model="generationNumberForm.standAttribute"
placeholder="请选择标准属性"
@change="standAttributeChange"
>
<el-option
v-for="(item, index) in standAttributeOption"
:label="item.qbCname"
:value="item.qbCode"
:key="item.qbCode + '-' + index"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="分类号" prop="classificationNumber" class="add-form-item">
<el-input
v-model="generationNumberForm.classificationNumber"
placeholder="请选择分类号"
clearable
readonly
@click.native="classClick"
></el-input>
</el-form-item>
<el-form-item label="顺序号" prop="sequenceNumber" class="add-form-item form-item-disabled">
<el-input
v-model="generationNumberForm.sequenceNumber"
placeholder="请选择顺序号"
disabled
></el-input>
</el-form-item>
<el-form-item label="年份" prop="year" class="add-form-item form-item-disabled">
<el-datePicker
v-model="generationNumberForm.year"
:editable="false"
type="year"
disabled
placeholder="选择年份">
</el-datePicker>
</el-form-item>
<el-form-item label="版本号" prop="versionNumber" class="add-form-item form-item-disabled">
<el-input
v-model="generationNumberForm.versionNumber"
placeholder="请输入版本号"
disabled
></el-input>
</el-form-item>
</el-form>
</div>
<div class="demo-drawer-footer">
<el-button round class="common-button-primary" icon="el-icon-check" type="primary" @click="isOk" :loading="submitLoading">确定</el-button>
<el-button round class="common-button-default" icon="el-icon-close" @click="visibleShow = false">取消</el-button>
</div>
</el-drawer>
<!--分类号抽屉-->
<el-drawer
:visible.sync="isClassDrawer"
title="分类号选择"
size="350px">
<laws-tree
:zNodes="zNodes"
deptSelect
:loading="loading"
treeDivId="depTreeInland"
@treeDblClick="(treeId, treeNode) => treeDbClick(treeId, treeNode)"
:editable="false"
ref="depTreeInland"
class="ztree" style="overflow: auto"
>
</laws-tree>
</el-drawer>
</div>
</template>
<script>
export default {
props: {
// 显示状态
isShow: {
type: Boolean,
default: false
},
title: {
type: String,
default: '选择企标'
}
},
data () {
return {
visibleShow: false,
// 生成编号form字段
generationNumberForm: {
standCode: 'SMTC', // 标准代号
standAttribute: '', // 标准属性
classificationNumber: '', // 分类号
classificationNumberId: '', // 分类号ID
sequenceNumber: '', // 顺序号
year: this.$moment(new Date()).format('YYYY'), // 年份
versionNumber: 'V1' // 版本号
},
// 生成编号form验证
generationNumberFormRules: {
standCode: [
{required: true, message: '标准代号不能为空', trigger: 'change'}
],
standAttribute: [
{required: true, message: '标准属性不能为空', trigger: 'change'}
],
classificationNumber: [
{required: true, message: '分类号不能为空', trigger: 'change'}
],
// sequenceNumber: [
// {required: true, message: '顺序号不能为空', trigger: 'change'}
// ],
year: [
{required: true, message: '年份不能为空', trigger: 'change'}
],
versionNumber: [
{required: true, message: '版本号不能为空', trigger: 'change'}
]
},
zNodes: [], // 分类号
// 标准属性字段数据
standAttributeOption: [],
isClassDrawer: false, // 分类号抽屉
flag: '', // 1是自定义,2是SVPPS
loading: false,
submitLoading: false
}
},
methods: {
// 关闭抽屉
close () {
this.visibleShow = false
},
// 抽屉确定事件
isOk () {
this.submitLoading = true
this.$refs['generationNumberForm'].validate((valid) => {
if (valid) {
this.getSeqNum().then(() => {
let generationNumberForm = this.generationNumberForm
// 拼接企标编号
let verNum = generationNumberForm.versionNumber.replace(/[^0-9]/ig,"");
let verEn= generationNumberForm.versionNumber.replace(/[^A-Z]+/ig,"");
let standCode = generationNumberForm.standCode + ' ' + generationNumberForm.standAttribute + ' ' +
generationNumberForm.classificationNumber + ' ' + generationNumberForm.sequenceNumber + '-' +
this.$moment(generationNumberForm.year).format('YYYY') + '' + generationNumberForm.versionNumber + ''
this.$emit('isOk', standCode, {
standCode: standCode,
qbCode: this.generationNumberForm.standAttribute, // 标准属性
classCode: this.generationNumberForm.classificationNumberId // 分类号
})
this.visibleShow = false
this.submitLoading = false
})
} else {
this.submitLoading = false
this.$message.warning('请检查表单是否填写正确')
}
})
},
// 选择分类号事件
treeDbClick (treeId, treeNode) {
if (this.flag === 1) {
this.generationNumberForm.classificationNumber = treeNode.number.length > 2 ? treeNode.number :
treeNode.number.length === 2 ? treeNode.number + '0' : treeNode.number + '00'
this.generationNumberForm.classificationNumberId = treeNode.id
} else {
this.generationNumberForm.classificationNumber = treeNode.svppsCode.length > 2 ? treeNode.svppsCode :
treeNode.svppsCode.length === 2 ? treeNode.svppsCode + '0' : treeNode.svppsCode + '00'
this.generationNumberForm.classificationNumberId = treeNode.id
}
this.isClassDrawer = false
},
// 根据标准属性和分类号获取顺序号
getSeqNum () {
return new Promise((resolve, reject) => {
this.$http.get('lawss/sarBussRecordsCode/createSeqNum', {
qbcode: this.generationNumberForm.standAttribute, // 标准属性
classCode: this.generationNumberForm.classificationNumberId // 分类号
}, {
_this: this
}, res => {
if (res.ok) {
this.generationNumberForm.sequenceNumber = res.data
resolve()
} else {
this.$message.warning(res.message)
}
})
})
},
// 标准属性change事件,查询分类号
standAttributeChange (val) {
this.loading = true
this.zNodes = []
this.generationNumberForm.classificationNumber = ''
this.$http.post('lawss/sarBussRecordsCode/queryByStandAttribute', {
code: val
}, {
_this: this
}, res => {
if (res.ok) {
let treeNode = []
// 1是自定义,2是SVPPS
this.flag = res.data.flag
if (res.data.flag === 1) {
res.data.rowList.map((item, index) => {
let treeItem = {
name: item.number + ' ' + item.name,
pId: item.pid,
id: item.id,
number: item.number,
rootNum: item.rootNum,
rank: item.rank
}
treeNode[index] = treeItem
})
} else {
res.data.rowList.map((item, index) => {
let treeItem = {
name: item.svppsCode + ' ' + item.svppsCnName + ' ' + item.svppsEnName,
pId: item.pid,
id: item.id,
svppsCode: item.svppsCode,
snum: item.snum,
fnum: item.fnum,
tnum: item.tnum
}
treeNode[index] = treeItem
})
}
this.zNodes = treeNode
} else {
this.$message.warning(res.message)
}
this.loading = false
})
},
// 分类号抽屉展示
classClick () {
if (this.generationNumberForm.standAttribute) {
this.isClassDrawer = true
} else {
this.$message.warning('请先选择标准属性')
}
},
// 查询标准属性数据
getQueryAll () {
this.$http.get('lawss/sarBussRecordsCode/queryAll', {}, {}, res => {
if (res.ok) {
this.standAttributeOption = res.data
} else {
this.$message.warning(res.message)
}
})
}
},
watch: {
isShow (val) {
this.$nextTick(() => {
this.$refs.generationNumberForm.resetFields()
})
this.visibleShow = val
},
visibleShow (val) {
this.$emit('update:isShow', val)
}
},
mounted () {
this.getQueryAll()
}
}
</script>
+62
View File
@@ -0,0 +1,62 @@
<!-- 暂无数据 -->
<template>
<div class="hasNoData" :class="pClass">
<div class="no-data-icon iconfont">
&#xe6f0;
<span>{{ tips }}</span>
</div>
</div>
</template>
<script>
export default {
name: 'index',
data () {
return {}
},
methods: {},
components: {},
props: {
pClass: String,
tips: {
type: String,
default: '暂无数据'
}
},
computed: {},
watch: {},
mounted () {}
}
</script>
<style lang="less">
.hasNoData {
display: flex;
display: -ms-flex;
justify-content: center;
align-items: center;
background: rgba(100, 100, 100, .05);
.no-data-icon {
min-width: 80px;
height: 80px;
display: flex;
display: -ms-flex;
justify-content: center;
align-items: center;
border-radius: 50%;
font-size: 50px;
flex-flow: column;
color: #AAA;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
span {
font-size: 14px;
font-weight: normal;
margin-top: 5px;
color: #AAA;
}
}
}
</style>
+53
View File
@@ -0,0 +1,53 @@
/**
* 自定义全局组件
* liuyan
* */
import Loading from './loading' // loading组件
import NavMenu from './navMenu' // 左侧菜单栏组件
import ComHeader from './comHeader' // header头部组件 面包屑、退出
import LawsTree from './lawsTree' // tree组件
import Pagination from './pagination' // table表格分页组件
import AdcBackTop from './backTop' // 回到顶部组件
import HasNoData from './hasNoData' // 暂无数据组件
import searchSelect from './searchSelect' // 下拉带搜索框组件
import DeptTree from './deptTree' // 组织机构树
import TableToolsBar from './tableToolsBar' // 表格工具栏
import PanelHeader from './panel/PanelHeader' // tabs
import PanelContent from './panel/PanelContent' // tabs 内容
import searchMultipleSelect from './searchMultipleSelect' // 下拉带搜索框-多选组件
import LabelInput from './labelInput' // 带label的输入框
import UEditor from './ueditor' // UEditor编辑器
import AdvancedQuery from './advancedQuery' // 高级查询
import GenerationNumber from './generationNumber' // 生成企标编号组件
import RoleUserTree from './roleUserTree' // 根据部门和角色查询人员
import DeptRoleTree from './deptRoleTree' // 根据部门查询角色
import SQTree from './SQTree'
import OrgTable from './OrgTable'
const install = function (Vue) {
Vue.component('loading', Loading)
Vue.component('navMenu', NavMenu)
Vue.component('comHeader', ComHeader)
Vue.component('lawsTree', LawsTree)
Vue.component('pagination', Pagination)
Vue.component('adcBackTop', AdcBackTop)
Vue.component('hasNoData', HasNoData)
Vue.component('searchSelect', searchSelect)
Vue.component('deptTree', DeptTree)
Vue.component('tableToolsBar', TableToolsBar)
Vue.component('PanelHeader', PanelHeader)
Vue.component('PanelContent', PanelContent)
Vue.component('searchMultipleSelect', searchMultipleSelect)
Vue.component('labelInput', LabelInput)
Vue.component('UEditor', UEditor)
Vue.component('AdvancedQuery', AdvancedQuery)
Vue.component('GenerationNumber', GenerationNumber)
Vue.component('RoleUserTree', RoleUserTree)
Vue.component('DeptRoleTree', DeptRoleTree)
Vue.component('SQTree', SQTree)
Vue.component('OrgTable', OrgTable)
}
export default {
install
}
+96
View File
@@ -0,0 +1,96 @@
<!-- 带label的输入框 -->
<!--
可接收一个width用于控制输入框长度
可接收一个placeholder用户显示待输入提示
可接收一个clearable用户是否包含清除按钮
可接收一个maxlength 用于限制输入框长度
-->
<template>
<div id="labelInput">
<label>{{ label }}</label>
<div class="label-input-content" :style="{ width: width + 'px' }">
<el-input :value="value" @input="handleChange" :maxlength="maxlength" :placeholder="placeholder" :clearable="clearable"></el-input>
</div>
</div>
</template>
<script>
export default {
name: 'index',
data () {
return {
currentValue: this.value
}
},
methods: {
handleChange (val) {
this.$emit('input', val)
}
},
components: {},
props: {
value: String,
label: String,
width: {
type: Number,
default: 200
},
maxlength: Number,
placeholder: String,
clearable: {
type: Boolean,
default: true
}
},
computed: {},
watch: {},
mounted () {}
}
</script>
<style lang="less">
#labelInput{
vertical-align: top;
label{
width: 88px;
display: inline-block;
border: 1px solid #DDD;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
border-right: none;
height: 32px;
line-height: 32px;
background: #F4F8FB;
padding: 0 7px;
text-align: center;
vertical-align: middle;
float: left;
font-size: 12px;
color: #515a6e;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.label-input-content{
display: inline-block;
.el-input{
display: inline-block;
width: 100%;
position: relative;
vertical-align: middle;
line-height: normal;
.el-input__inner{
height: 32px;
line-height: 32px;
font-size: 12px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.el-input__suffix{
.el-icon-circle-close{
line-height: 32px;
}
}
}
}
}
</style>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+85
View File
@@ -0,0 +1,85 @@
<!-- loading组件 liuyan -->
<template>
<div class="loading-box" :style="style" v-if="loading">
<div class="loading-content">
<i class="i-icon el-icon-loading spin-loading"></i>
<div class="loading-tips">
<slot></slot>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'local-loading',
props: {
// 是否显示隐藏
loading: {
type: Boolean,
default: false
},
// 是否固定
fixed: {
type: Boolean,
default: false
},
// 固定依据元素
el: {
type: String,
default: '.container-box'
}
},
data() {
return {
style: {}
}
},
mounted() {
if (this.fixed) {
const el = $(this.el)
const top = `${el.offset().top}px`
const left = `${el.offset().left}px`
const width = `${el.outerWidth()}px`
const height = `${el.outerHeight()}px`
this.style = {
position: 'fixed',
top,
left,
width,
height,
'z-index': 1000
}
}
}
}
</script>
<style lang="less">
.loading-box{
position: absolute;
top: 0;
left: 0;
z-index: 8;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.9);
border-radius: 8px;
user-select: none;
.loading-content{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #3391CE;
text-align: center;
.spin-loading{
animation: rotating 2s linear infinite;
}
.loading-tips{
margin-top: 5px;
font-size: 12px;
}
}
}
</style>
+591
View File
@@ -0,0 +1,591 @@
<!--左侧导航菜单 liuyan -->
<template>
<div class="nav-menu v-class" :class="{'is-collapse': isCollapse}">
<div class="logo">
<img :src="logo" />
</div>
<el-menu
unique-opened
:default-active="defaultActive"
background-color="#013483"
text-color="#ffffff"
active-text-color="#ffd04b"
router
:collapse="isCollapse"
>
<template v-for="(item, index) in navMenuList">
<el-submenu
:key="index"
:index="item.path"
popper-class="nav-menu-popper"
v-if="!item.isChildren && (!item.menuId || $hasPermission(item.menuId))"
>
<template slot="title">
<i class="shangqi-icon" :class="item['icon-class']"></i>
<span>{{ item.title }}</span>
<el-badge is-dot class="has-no-read" v-if="item.title === '个人中心' && getDynamicTotal.allCount">
</el-badge>
</template>
<el-menu-item
v-for="(children, childrenIndex) in item.children"
:key="childrenIndex"
:index="children.path"
v-if="!children.menuId || $hasPermission(children.menuId)"itemSplitInfo
>
<el-badge :value="getDynamicTotal.msgCount" class="item" v-if="children.title === '我的消息' && getDynamicTotal.msgCount !== 0">
{{ children.title }}
</el-badge>
<el-badge :value="getDynamicTotal.shareCount" class="item" v-else-if="children.title === '我的推送' && getDynamicTotal.shareCount !== 0">
{{ children.title }}
</el-badge>
<el-badge :value="getDynamicTotal.myStandCount" class="item" v-else-if="children.title === '我的企标' && getDynamicTotal.myStandCount !== 0">
{{ children.title }}
</el-badge>
<div v-else>
{{ children.title }}
</div>
</el-menu-item>
</el-submenu>
<el-menu-item
:key="index"
:index="item.path"
v-if="item.isChildren && (!item.menuId || $hasPermission(item.menuId))"
>
<i class="shangqi-icon" :class="item['icon-class']"></i>
<span slot="title">{{ item.title }}</span>
</el-menu-item>
</template>
</el-menu>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'NavMenu',
data () {
return {
defaultActive: null, // 当前激活菜单的 index
navMenuList: [
{
title: '首页',
path: '/home',
isChildren: true, // 判断没有子菜单
'icon-class': 'home'
},
{
title: '标准法规库',
path: '/regulatoryRepository',
'icon-class': 'fagui',
menuId: 'PMYP5AG3M2',
children: [
{
title: '动态&资料',
path: '/dynamicInformation',
menuId: 'RAFQ4N4ARF'
},
{
title: '国内标准法规',
path: '/domesticStandardsAndRegulations',
menuId: 'A59EFAQ7AC'
},
{
title: '海外标准法规',
path: '/foreignStandardsAndRegulations',
menuId: '6K8A2RZYRE'
},
{
title: '国内外政策',
path: '/foreignRegulationsDatabase',
menuId: '4DB4Y2H3NH'
},
// // {
// // title: '标准制修订管理',
// // path: '/demo2One'
// // },
{
title: '标准法规清单',
path: '/accessStandardsAndRegulations',
menuId: 'UR3CSDWEQM6Q2GEW339L'
},
// {
// title: '标准法规清单详情',
// path: '/details'
// }
// // {
// // title: '试验项目库',
// // path: '/demo2One'
// // },
// // {
// // title: '本地产品/项目库',
// // path: '/localProductsOrProjectLibrary'
// // },
{
title: '企业标准库',
path: '/enterpriseStandardDatabase',
menuId: '3YVZP8R4TC'
},
{
title: '企标制修订计划',
path: '/enterBSysRevPlanManaLib',
menuId: 'WW7YDHQ9Z679TGMDZMUS'
},
// {
// title: '子公司标准库',
// path: '/subsidiaryStandardLibrary'
// }
{
title: '车型/项目库',
path: '/localProductsOrProjectLibrary',
menuId: 'PCZKM8TQJAH5UP5EAXTJ'
},
{
title: '未符合项跟踪',
path: '/nonConfomity',
menuId: 'HQSK8WWPDJG7R5F53LTK'
},
{
title: '标准法规工作组',
path: '/workGroup',
menuId: 'QYRMD5TUNBP9XXFRNK5S'
},
{
title: '备案产品标准库',
path: '/enterpriseStandardFiling',
menuId: 'MQBAGJQMSRZDRX3X5AVR'
},
{
title: '标准合规评估结果', // 把 标准涉及项目 这几个字 改成 标准合规评估结果
path: '/standInvolveProject',
menuId: 'JURHS3LVP35US88ABULS'
}
// {
// title: '动态信息',
// path: '/information',
// menuId: 'ULUBXHYQB8M3XQ9HS9QG'
// }
]
},
{
title: '工作台',
path: '/processCenter',
'icon-class': 'liucheng',
menuId: '6GDJ5JDHUS',
children: [
{
title: '流程中心',
path: '/processCenter'
},
{
title: '发起流程',
path: '/createProcessNew'
},
// {
// title: '标准法规管理流程',
// path: '/newProcess/1'
// },
// {
// title: '政策管理流程',
// path: '/newProcess/2'
// },
// {
// title: '企标管理流程',
// path: '/newProcess/3'
// },
// {
// title: '标准采购翻译申请流程',
// path: '/newProcess/4'
// },
// {
// title: '工作组会议管理流程',
// path: '/newProcess/5'
// },
// {
// title: '标准法规清单管理流程',
// path: '/newProcess/6'
// }
]
},
{
title: '本地工具',
path: '/localTool',
'icon-class': 'tools',
menuId: 'F3RJJEMLK8',
children: [
// {
// title: '标准预警',
// path: '/standardWarning'
// },
{
title: '标准内容自动识别',
path: '/standardRecognition',
menuId: '27RCLPSNL22JAMJ2MBTZ'
},
{
title: '标准拆分',
path: '/standAutoSplit',
menuId: 'B8UYM3WFCMGXR2BPF9JA'
},
{
title: '标准比对',
path: '/standContrast',
menuId: '3RYN5FLTTDYP7D2PJ44H'
},
{
title: '标准比对库',
path: '/standardComparisonLibrary',
menuId: 'AH56UDHHBVF5V7WZFWJQ'
}
// {
// title: '预警管理',
// path: '/warningManage'
// },
// {
// title: '动态&通知管理',
// path: '/dynamicInformationManage'
// },
// {
// title: '标准编号申领',
// path: '/applicationStandardNumber'
// },
]
},
{
title: '标准预警',
path: '/standardWarning',
'icon-class': 'warning',
menuId: 'ABCLRLJUQN44ENBS93CQ',
isChildren: true // 判断没有子菜单
},
// {
// title: '技术要求清单',
// path: '/skillReq',
// children: [
// {
// title: '技术要求清单查看',
// path: '/SkillReqSee'
// },
// {
// title: '技术要求清单管理',
// path: '/SkillReqAdd'
// }
// ]
// },
{
title: '配置管理',
path: '/config',
'icon-class': 'conf',
menuId: '95KGANGWCV',
children: [
{
title: '标准法规属性管理',
path: '/standLawsAttrManage',
menuId: 'C5VHBSYRMA'
},
{
title: '资料中心管理',
path: '/dynamicInformationManage',
menuId: '6V2QZ9STRZ'
},
{
title: '机构管理',
path: '/MechanismManage',
menuId: '7MWCQK6NNH'
},
{
title: '角色管理',
path: '/roleManage',
menuId: 'NVU76EMB7N'
},
{
title: '用户管理',
path: '/userManage',
menuId: 'YRJUEVJVUJ'
},
{
title: '系统配置管理',
path: '/warningTimeSetting',
menuId: 'H2KC6P3PPM'
},
{
title: '文档转换监控',
path: '/convertDocView',
menuId: '3F52K25546'
},
// {
// title: '菜单管理',
// path: '/menuManage'
// },
// {
// title: '保密管理',
// path: '/convertDocView'
// },
{
title: '动态信息管理',
path: '/DynamicInformations',
menuId: '3C87BSHJUF'
},
{
title: '标准属性自定义',
path: '/attributeCustom',
menuId: 'PGPZXNUFEXC85BVPV9AU'
},
// {
// title: '流程分类管理',
// path: '/processClassificationManage',
// menuId: 'N323F2UB9FTUV5SD3GTD'
// },
// {
// title: '流程管理',
// path: '/processManage',
// menuId: 'K5KXSS3X9CF7CS8AMFJ5'
// },
{
title: 'SVPPS',
path: '/svpps',
menuId: 'AR52RX586LQHVZSVV83K'
},
{
title: '企标编号管理体系',
path: '/enterpriseStandardNumberManagement',
menuId: '9YSFG39S3CBFUJCEU3QX'
}
]
},
{
title: '个人中心',
path: '/personal',
'icon-class': 'ucenter',
menuId: 'ZY9RFA4M35',
children: [
{
title: '我的消息',
path: '/dynamics',
menuId: 'JCEV4AEV32'
},
{
title: '我的企标',
path: '/MyEnterpriseStandard',
menuId: 'LKU3W23UMEHDM9VLDHGK'
},
{
title: '我的收藏',
path: '/collection',
menuId: 'JY5LKL2HPD'
},
{
title: '我的浏览',
path: '/browsing',
menuId: 'HAEY2A4LMX'
},
{
title: '已收分享',
path: '/push',
menuId: '9F8T7DPYHE'
},
{
title: '已发分享',
path: '/forward',
menuId: 'K45Y9TGKZV2K4XP4CETD'
},
{
title: '我的问答',
path: '/questionsAndAnswers',
menuId: '8VKLZATQQG4NQHXV9UDS'
},
{
title: '我的板块',
path: '/plate',
menuId: 'TUYHX8JBWV'
}
// {
// title: '个人信息',
// path: '/info',
// menuId: '8K7FDHG89G'
// }
]
},
{
title: '搜索中心',
path: '/advancedSearch',
'icon-class': 'search',
menuId: 'K9BAYUPZBC',
isChildren: true // 判断没有子菜单
},
// {
// title: '标准比对库',
// path: '/standardComparisonLibrary',
// 'icon-class': 'search',
// menuId: 'Q32VBYVGCAE4XXN3XZ8T',
// isChildren: true // 判断没有子菜单
// }
// {
// title: '自定义报表',
// path: '/customReport',
// 'icon-class': 'baobiao',
// isChildren: true // 判断没有子菜单
// }
]
}
},
created () {
// 获取当前页的path,赋值没左侧菜单,并展开
if (this.$route.meta.parentPath) {
this.defaultActive = this.$route.meta.parentPath
} else {
this.defaultActive = this.$route.path
}
},
mounted () {
},
computed: {
logo () {
return this.isCollapse ? require('assets/images/shangqi/img/logo-isCollapse.png') : require('assets/images/shangqi/img/logo.png')
},
...mapGetters(['getDynamicTotal', 'isCollapse'])
},
watch: {
// 监听路由 重新渲染面包屑
$route () {
// 获取当前页的path,赋值没左侧菜单,并展开
if (this.$route.meta.parentPath) {
this.defaultActive = this.$route.meta.parentPath
} else {
this.defaultActive = this.$route.path
}
}
}
}
</script>
<style lang="less" scoped>
@import '~@/assets/styles/mixins';
.nav-menu {
height: 100%;
overflow-y: auto;
user-select: none;
box-sizing: border-box;
background: url("~assets/images/shangqi/sideBar/side-bar-isCollapse-bg.png") no-repeat;
background-size: 100% 100%;
&:not(.is-collapse) {
width: 212px;
background: url("~assets/images/shangqi/sideBar/side-bar-bg.png") no-repeat;
background-size: 100% 100%;
.logo {
img {
width: 115px;
height: 43px;
}
}
}
.logo{
text-align: center;
padding: 15px 0;
img {
width: 36px;
height: 35px;
}
}
}
.has-no-read{
position: relative;
top:-15px;
left:10px
}
.nav-menu{
scrollbar-width: none;
-ms-overflow-style: none; /* IE 10+ */
}
.nav-menu::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
.el-menu-item {
span {
font-weight: normal;
margin-left: 5px;
}
.shangqi-icon {
display: inline-block;
width: 18px;
height: 18px;
background-repeat: no-repeat;
background-size: 85% 85%;
background-position: center center;
&.home {
background-image: url("~assets/images/shangqi/sideBar/home.png");
}
&.baobiao {
background-image: url("~assets/images/shangqi/sideBar/baobiao.png");
}
&.ucenter {
background-image: url("~assets/images/shangqi/sideBar/ucenter.png");
}
&.search {
background-image: url("~assets/images/shangqi/sideBar/search.png");
}
&.warning {
background-image: url("~assets/images/shangqi/sideBar/warning.png");
}
&.liucheng {
background-image: url("~assets/images/shangqi/sideBar/liucheng.png");
}
}
}
.el-submenu {
/deep/.el-submenu__title {
span {
font-weight: normal;
margin-left: 5px;
}
.shangqi-icon {
display: inline-block;
width: 18px;
height: 18px;
background-repeat: no-repeat;
background-size: 85% 85%;
background-position: center center;
&.fagui {
background-image: url("~assets/images/shangqi/sideBar/fagui.png");
}
&.tools {
background-image: url("~assets/images/shangqi/sideBar/tools.png");
}
&.ucenter {
background-image: url("~assets/images/shangqi/sideBar/ucenter.png");
}
&.search {
background-image: url("~assets/images/shangqi/sideBar/search.png");
}
&.conf {
background-image: url("~assets/images/shangqi/sideBar/conf.png");
}
&.liucheng {
background-image: url("~assets/images/shangqi/sideBar/liucheng.png");
}
}
}
.el-menu-item {
padding-left: 29px !important;
div {
font-weight: normal;
}
}
/deep/.el-menu {
padding-left: 18px;
}
}
.el-menu--collapse{
.shangqi-icon{
width: 24px;
height: 24px;
}
.el-submenu{
/deep/.el-submenu__title{
.shangqi-icon{
width: 24px;
height: 24px;
}
}
}
}
</style>
+548
View File
@@ -0,0 +1,548 @@
<!-- 在线编辑 -->
<template>
<transition name="fade">
<div class="t-wrap" v-if="visible">
<div class="only-office-edit">
<div class="ooe-header">
在线编辑
<div class="close-btn iconfont" @click="handleClose">&#xe67d;</div>
</div>
<div class="ooe-wrap">
<div class="ooe-body">
<div class="b-left">
<laws-tree
tree-div-id="onlyOffice"
ref="onlyOfficeTree"
:z-nodes="zNodes"
:prevent-right-click-node="['1', '2', '3']"
root-cant-select
show-r-menu
expand-first
@treeAdd="handleTreeAdd"
@treeEdit="handleTreeEdit"
@treeRemove="handleTreeRemove"
@treeClick="handleTreeClick"
></laws-tree>
</div>
<div class="b-right">
<ul class="b-right-top">
<li>
<span>中文名称:</span>
<p>{{ standName }}</p>
</li>
<li>
<span>英文名称:</span>
<p>{{ standENName }}</p>
</li>
</ul>
<div class="b-right-bottom">
<div class="no-data" v-if="onlyOfficeUrl === ''">请选择标准</div>
<iframe id="onlyOffice" :src="onlyOfficeUrl" frameborder="0" v-else></iframe>
</div>
</div>
</div>
<div class="ooe-footer">
<el-button size="mini" @click="handleClose"> </el-button>
<el-button type="primary" size="mini" @click="handleSave"> </el-button>
</div>
<loading :loading="loading.loadOffice">正在加载文件</loading>
<loading :loading="loading.saving">正在保存</loading>
</div>
</div>
<el-dialog
title="新增节点"
:visible.sync="dialogVisible"
append-to-body
:close-on-click-modal="false"
@close="handleDialogClose"
width="350px">
<el-form ref="itemsNodeForm" :model="itemsNode" :rules="itemsNodeRules">
<el-form-item label="中文名称" prop="standName">
<el-input v-model="itemsNode.standName" max-length="100" placeholder="请输入中文名称" clearable></el-input>
</el-form-item>
<el-form-item label="英文名称" prop="standENName">
<el-input v-model="itemsNode.standENName" max-length="1000" placeholder="请输入英文名称" clearable></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button size="mini" @click="handleDialogClose"> </el-button>
<el-button type="primary" size="mini" @click="handleDialogConfirm"> </el-button>
</div>
</el-dialog>
</div>
</transition>
</template>
<script>
import {
officeInit,
getChapter,
generateStandFile
} from 'api/onlyOffice'
export default {
name: 'onlyOfficeEdit',
mixins: [],
props: {
visible: {
type: Boolean,
default: false
}
},
components: {},
data () {
return {
standName: '--',
standENName: '--',
currentNodeId: '',
zNodes: [
{
id: 'root',
name: '总目录',
pId: null,
isParent: true
},
{
id: '1',
name: '前言',
pId: 'root',
isParent: false,
icon: require('@/assets/images/shangqi/img/file.png')
},
{
id: '2',
name: '范围',
pId: 'root',
isParent: false,
icon: require('@/assets/images/shangqi/img/file.png'),
chapter: 1
},
{
id: '3',
name: '规范性引用文件',
pId: 'root',
isParent: false,
icon: require('@/assets/images/shangqi/img/file.png'),
chapter: 2
}
],
dialogVisible: false,
itemsNode: {
pId: '',
pNodeName: '',
id: '',
standName: '',
standENName: ''
},
itemsNodeRules: {
pNodeName: [
{ required: true, message: '父节点不能为空', trigger: 'blur' }
],
standName: [
{ required: true, message: '条款号不能为空', trigger: 'blur' }
],
standENName: [
{ required: true, message: '条款名称不能为空', trigger: 'blur' }
]
},
onlyOfficeUrl: '',
loading: {
loadOffice: false,
saving: false
},
officeInitData: {
// 规范性引用文件
normative: '',
// 前言
preface: '',
// 范围
range: ''
},
// 企标编号
standNo: ''
}
},
methods: {
handleClose() {
this.$confirm('请确认是否保存在线编辑文件?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
confirmButtonClass: 'common-button-primary',
roundButton: true,
type: 'warning'
}).then(() => {
// 先执行保存再退出在线编辑
this.handleSave()
}).catch(() => {
this.onlyOfficeUrl = ''
this.standName = ''
this.standENName = ''
this.$emit('update:visible', false)
})
},
handleTreeAdd(treeId, treeNode) {
const chapter = treeNode.chapter ? `${treeNode.chapter}.${treeNode.children ? treeNode.children.length : 1}` : `${treeNode.children ? treeNode.children.length : 1}`
this.itemsNode = {
pId: treeNode.id,
pNodeName: treeNode.oldname || treeNode.name,
id: `node-${new Date().getTime()}`,
standName: '',
standENName: '',
chapter
}
setTimeout(() => {
this.dialogVisible = true
}, 100)
},
handleTreeEdit(treeId, treeNode) {},
handleTreeRemove(treeId, treeNode) {
this.$confirm('您是否确定删除该节点?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$refs['onlyOfficeTree'].removeNode(treeNode)
if (this.currentNodeId === treeNode.id) {
this.itemsNode = {
pId: '',
pNodeName: '',
standName: '',
standENName: '',
chapter: ''
}
this.currentNodeId = ''
this.onlyOfficeUrl = ''
}
}).catch(() => {})
},
handleDialogClose() {
this.$refs['itemsNodeForm'].clearValidate()
setTimeout(() => {
this.dialogVisible = false
this.itemsNode = {
pId: '',
pNodeName: '',
standName: '',
standENName: '',
chapter: ''
}
this.onlyOfficeUrl = ''
}, 100)
},
handleDialogConfirm() {
this.$refs['itemsNodeForm'].validate(valid => {
if (valid) {
this.$refs['onlyOfficeTree'].addNode({
id: this.itemsNode.id,
name: `${this.itemsNode.chapter} ${this.itemsNode.standName}`,
pId: this.itemsNode.pId,
standName: this.itemsNode.standName,
standENName: this.itemsNode.standENName,
chapter: this.itemsNode.chapter,
icon: require('@/assets/images/shangqi/img/file.png')
})
setTimeout(() => {
this.$message.success('添加成功')
this.handleDialogClose()
}, 100)
}
})
},
/**
* @description: 保存
* @date: 2021-01-26 23:19:54
* @auth: chenxiaoxi
*/
handleSave() {
this.loading.saving = true
let allNode = this.$refs['onlyOfficeTree'].transformToArray()
allNode.splice(0, 4)
const chapterList = []
allNode.map(item => {
chapterList.push({
id: item.id,
pId: item.pId,
chapter: item.chapter,
standENName: item.standENName,
standName: item.standName
})
})
generateStandFile({
chapterList,
standCode: this.standNo
}).then(res => {
this.loading.saving = false
if (res.ok) {
this.$message.success('保存成功')
setTimeout(() => {
this.onlyOfficeUrl = ''
this.standName = ''
this.standENName = ''
this.$emit('update:visible', false)
}, 1000)
} else {
this.$message.warning(res.message)
}
}).catch(e => {
this.loading.saving = false
})
},
/**
* @description: 条款点击
* @date: 2021-01-10 16:34:10
* @auth: chenxiaoxi
*/
handleTreeClick(treeId, treeNode) {
if (treeNode.children && treeNode.id !== 'root') {
this.$message.warning('请对子节点进行编辑')
return false
}
this.standName = treeNode.standName
this.standENName = treeNode.standENName
this.currentNodeId = treeNode.id
let fileName = ''
switch (treeNode.id) {
case '1':
const prefaceURL = this.officeInitData.preface
fileName = prefaceURL.split('/')
fileName = fileName[fileName.length - 1]
this.onlyOfficeUrl = `/static/onlyOffice/editor.html?fileName=${fileName}&fileUrl=${prefaceURL}&fileType=docx&standNo=${this.standNo}&key=${treeNode.id}${new Date().getTime()}`
break
case '2':
const rangeURL = this.officeInitData.range
fileName = rangeURL.split('/')
fileName = fileName[fileName.length - 1]
this.onlyOfficeUrl = `/static/onlyOffice/editor.html?fileName=${fileName}&fileUrl=${rangeURL}&fileType=docx&standNo=${this.standNo}&key=${treeNode.id}${new Date().getTime()}`
break
case '3':
const normativeURL = this.officeInitData.normative
fileName = normativeURL.split('/')
fileName = fileName[fileName.length - 1]
this.onlyOfficeUrl = `/static/onlyOffice/editor.html?fileName=${fileName}&fileUrl=${normativeURL}&fileType=docx&standNo=${this.standNo}&key=${treeNode.id}${new Date().getTime()}`
break
default:
this.getChapter(treeNode.chapter)
.then(fileURL => {
fileName = fileURL.split('/')
fileName = fileName[fileName.length - 1]
this.onlyOfficeUrl = `/static/onlyOffice/editor.html?fileName=${fileName}&fileUrl=${fileURL}&fileType=docx&standNo=${this.standNo}&key=${treeNode.id}${new Date().getTime()}`
})
}
},
/**
* @description: 加载章节
* @date: 2021-01-27 02:02:12
* @auth: chenxiaoxi
*/
getChapter(chapter) {
return new Promise((resolve, reject) => {
getChapter({
standNo: this.standNo,
chapter
}).then(res => {
if (res.ok) {
resolve(res.data)
} else {
this.$message.warning(res.message)
}
}).catch(e => {})
})
},
// 获取企标对应文件 如果企标文件不存在则直接传空字符串或为null即可
getBusStandFileByAttId (fileId) {
this.$http.get('att/attFile/getBusStandFileByAttId', {
attId: fileId
}, {
_this: this
}, res => {
if (res.ok) {
const editFileInfo = res.data
// 此处将返回的ATT对象追加到标准文本的集合中
if (fileId !== null && fileId === '') {
const { id } = editFileInfo
if (this.prcForm['standFile']) {
this.prcForm['standFile'] += id + ','
} else {
this.prcForm['standFile'] = id + ','
}
}
const nowTime = new Date().getTime()
this.onlyOfficeUrl = '/static/onlyOffice/editor.html?fileName=' + editFileInfo.oldFileName + '&fileType=' + editFileInfo.fileSuffix + '&attId=' + editFileInfo.id + '&fileUrl=' + editFileInfo.downLoadUrl + '&key=' + editFileInfo.id + nowTime
} else {
this.$message.error(res.message)
}
}, e => {}
)
},
/**
* @description: office初始化
* @date: 2021-01-26 21:14:54
* @auth: chenxiaoxi
*/
officeInit(standNo) {
this.standNo = standNo
this.loading.loadOffice = true
officeInit({
standNo
}).then(res => {
this.loading.loadOffice = false
if (res.ok) {
this.officeInitData = { ...res.data }
} else {
this.$message.warning(res.message)
}
}).catch(e => {
this.loading.loadOffice = false
})
}
},
computed: {},
watch: {},
mounted () {}
}
</script>
<style lang="less" scoped>
.fade-enter {
opacity: 0;
transform: scale(0.95);
}
.fade-enter-active {
transition: all .2s;
}
.fade-leave-to {
opacity: 0;
}
.fade-leave-active {
transition: opacity .2s;
}
.t-wrap {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
color: #333;
text-align: left;
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
.only-office-edit {
width: 100%;
height: 100%;
background: #f5f5f5;
display: flex;
flex-direction: column;
.ooe-header {
border-bottom: 1px solid #e8eaec;
height: 50px;
line-height: 50px;
font-size: 16px;
padding: 0 10px;
position: relative;
background: #fff;
.close-btn {
position: absolute;
top: 50%;
right: 10px;
width: 20px;
height: 20px;
color: #999;
margin-top: -10px;
font-size: 12px;
line-height: 20px;
&:hover {
color: inherit;
cursor: pointer;
}
}
}
.ooe-wrap {
position: relative;
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
.ooe-body {
flex: auto;
overflow: hidden;
display: flex;
position: relative;
.b-left {
width: 299px;
//height: 100%;
border-right: 1px solid #ddd;
margin-right: 10px;
background: #fff;
}
.b-right {
width: calc(~'100% - 299px');
//height: 100%;
border-left: 1px solid #ddd;
display: flex;
flex-direction: column;
padding: 0 10px 10px;
background: #fff;
.b-right-top {
li {
display: flex;
span {
color: #999;
margin-right: 5px;
}
p {
color: #666;
}
}
}
.b-right-bottom {
flex: 1;
overflow: hidden;
border: 1px solid #ddd;
display: flex;
.no-data {
background: #eee;
width: 100%;
//height: 100%;
flex: auto;
display: flex;
align-items: center;
justify-content: center;
color: #c1c1c1;
}
#onlyOffice {
width: 100%;
height: 100%;
}
}
}
}
.ooe-footer {
height: 50px;
border: 1px solid #e8eaec;
text-align: right;
background: #fff;
padding: 0 10px;
}
}
.laws-tree {
line-height: 20px;
}
}
.loading-box {
line-height: normal;
}
}
</style>
+121
View File
@@ -0,0 +1,121 @@
<!-- 分页 -->
<template>
<div class="pagination">
<!--<el-divider v-if="isDivider" />-->
<div class="pagination-slot">
<slot>
<el-pagination
:total="total"
:current-page="page"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageSize"
@current-change="pageChange"
@size-change="pageSizeChange"
layout="total, prev, pager, next, sizes, jumper"
/>
</slot>
</div>
</div>
</template>
<script>
import { mapGetters, mapMutations } from 'vuex'
export default {
name: 'pagination',
methods: {
// 切换页码
pageChange (page) {
this.$emit('pageChange', page)
},
pageSizeChange (pageSize) {
if (this.getTypeFlag === 'CloudRepository') {
this.userInfo.configContent = pageSize
this.setUserInfo(JSON.stringify(JSON.parse(JSON.stringify(this.userInfo))))
this.$emit('pageSizeChange', pageSize)
} else {
this.pageConfig(pageSize).then((res) => {
if (res.ok) {
this.userInfo.configContent = pageSize
this.setUserInfo(JSON.stringify(JSON.parse(JSON.stringify(this.userInfo))))
this.$emit('pageSizeChange', pageSize)
}
}, e => {
})
}
},
/**
* @description: 每页条数配置
* @author: chenxiaoxi
* @date: 2018/10/22 10:50:39
*/
pageConfig (pageSize) {
return new Promise((resolve, reject) => {
this.$http.postData('person/userConfig/createUserConfig', {
configType: 'PAGE_SIZE',
configContent: 20
}, {
loading: 'loading',
_this: this
}, res => {
resolve(res)
}, e => {
reject(e)
})
})
},
...mapMutations(['setUserInfo'])
},
props: {
total: {
type: Number
},
page: {
type: Number,
default: 0
},
// 是否隐藏 分割线
isDivider: {
type: Boolean,
default: true
}
},
computed: {
...mapGetters(['userInfo', 'getTypeFlag']),
pageSize () {
return this.userInfo.configContent === '' || this.userInfo.configContent === undefined || this.userInfo.configContent === null ? 20 : parseInt(this.userInfo.configContent)
}
},
mounted () {
}
}
</script>
<style lang="less">
.pagination {
width: 100%;
position: absolute;
bottom: 0;
left: 0;
background: #ffffff;
z-index: 999;
.pagination-slot {
width: 100%;
height: 56px;
/*line-height: 56px;*/
padding: 0 15px;
box-sizing: border-box;
.el-pagination{
display: flex;
align-items: center;
height: 100%;
.btn-prev{
.el-pager{
& > li{
/*line-height: 56px !important;*/
}
}
}
}
}
}
</style>
+22
View File
@@ -0,0 +1,22 @@
<template>
<div class="panel-content">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'panel-content'
}
</script>
<style lang="less">
@import '~@/assets/styles/style';
.panel-content{
width: 100%;
height: calc(~'100% - 30px');
position: relative;
background: @subContainerContentColor;
overflow: hidden;
}
</style>
+111
View File
@@ -0,0 +1,111 @@
<template>
<div class="panel-header test-1">
<ul class="tabs">
<li
v-for="(item, index) in tabs"
:key="index"
:class="{ 'active border-right': active === item.name}"
@click="activated(item.name, item.title)"
>
{{ item.title}}
</li>
</ul>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'panel-header',
methods: {
// 组件切换
activated (name, title) {
this.$emit('activated', name, title)
}
},
props: {
tabs: {
type: Array,
required: true
},
active: String
},
computed: {
...mapGetters(['getItemList'])
}
}
</script>
<style lang="less" scoped>
@import '~@/assets/styles/style';
@import '~@/assets/styles/mixins';
.panel-header {
width: 100%;
box-sizing: border-box;
border-bottom: 1px solid #CCCDCE;
background: #F0F0F0;
height: 30px;
position: relative;
.tabs{
white-space: nowrap;
position: absolute;
bottom: 0;
margin-block-start: 0;
margin-block-end: 0;
padding-inline-start: 0;
height: auto;
font-size: 0;
padding-left: 10px;
li{
display: inline-block;
vertical-align: baseline;
padding: 0 8px;
height: 28px;
line-height: 28px;
max-width: 150px;
text-align: center;
cursor: pointer;
user-select: none;
.ellipsis();
font-size: 14px;
border: 1px solid transparent;
border-bottom: none;
&.active{
height: 29px;
position: relative;
top: 1px;
background: @subContainerContentColor;
border-top: 1px solid #CCCCCC;
border-left: 1px solid #CFCFCF;
border-right: 1px solid #CFCFCF;
box-sizing: border-box;
color: @baseColor;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
&::before{
height: calc(~'100% + 1px');
top: -1px;
}
}
}
}
.test-1::-webkit-scrollbar {
/*滚动条整体样式*/
width : 10px; /*高宽分别对应横竖滚动条的尺寸*/
height: 2px;
}
.test-1::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
box-shadow : inset 0 0 5px rgba(0, 0, 0, 0.2);
background : #cecece;
}
.test-1::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow : inset 0 0 5px rgba(0, 0, 0, 0.2);
border-radius: 10px;
background : #ededed;
}
</style>
+138
View File
@@ -0,0 +1,138 @@
<template>
<div class="header">
<div class="header-left">
<span class="logo" @click="toHome" title="回到首页"></span>
</div>
<div class="header-right">
<span class="date">{{currentTime}}</span>
<span class="divide-line"> | </span>
<span class="user-img"></span>
<span class="user">您好{{ $store.getters.userInfo.uName }}</span>
<div class="user-info-panel-setting" @click.prevent="userInfoVisible = !userInfoVisible">
<el-dropdown
trigger="click"
:visible="userInfoVisible"
@command="userInfoOpen"
>
<div class="iconfont" style="color: #fff;"><i class="el-icon-arrow-down"></i></div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item name="logout" command="logout">{{$t('m.exit')}}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
</template>
<script>
import {mapGetters, mapMutations} from 'vuex'
export default {
name: 'useImg',
data () {
return {
// 当前系统时间
currentTime: '',
userInfoVisible: false
}
},
methods: {
toHome () {
this.$router.push('/home')
},
// 获取当前时间
getTime () {
this.currentTime = this.$dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss')
},
// 用户菜单栏点击
userInfoOpen (name) {
switch (name) {
case 'personal':
this.$router.push('/personal')
break
case 'logout':
this.$confirm('您确认要退出吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
confirmButtonClass: 'common-button-primary',
roundButton: true
}).then(() => {
this.userLoginOut()
}).catch(() => {})
break
}
},
// 用户退出登录
userLoginOut () {
this.$http.get('logout', {}, {
_this: this
}, res => {
this.$store.dispatch('logout')
this.$router.push('/sign_in')
}, e => {})
},
...mapMutations(['setProcess', 'setDynamicTotal'])
},
mounted () {
this.getTime()
},
computed: {
// 用户头像
userAvator () {
return this.$store.getters.userInfo.avator || require('@/assets/images/avator_default.png')
},
uName () {
return this.$store.getters.userInfo.uName
},
...mapGetters(['getDynamicTotal', 'getMenuList'])
}
}
</script>
<style lang="less" scoped>
.header{
display: flex;
justify-content: space-between;
color: #fff;
.header-left{
text-align: left;
width: 50%;
.logo {
display: inline-block;
width: 160px;
height: 61px;
background: url("~@/assets/images/shangqi/home/logo-bg.png") no-repeat;
background-size: cover;
cursor: pointer;
}
}
.header-right{
width: 49%;
text-align: right;
line-height: 61px;
height: 61px;
display: flex;
justify-content: flex-end;
align-items: center;
.date{
display: inline-block;
margin-right: 20px;
}
.user-img{
display: inline-block;
width: 20px;
height: 21px;
background: url("~@/assets/images/shangqi/home/user-img.png") no-repeat;
background-size: 100% 100%;
margin-right: 15px;
}
.divide-line{
display: inline-block;
margin-right: 20px;
}
.user{
display: inline-block;
}
}
}
</style>
+314
View File
@@ -0,0 +1,314 @@
<!--根据角色和部门选人抽屉-->
<template>
<el-drawer
append-to-body
:title="title"
size="400px"
:visible.sync="isVisible"
:wrapper-closable="false"
@close="handleTreeDrawerCancel"
>
<div class="demo-drawer-content">
<laws-tree
v-if="isVisible"
expandAll
ref="roleUserTree"
:zNodes="zNodes"
:check-enable="checkEnable"
treeDivId="roleUserTree"
:editable="false"
:onlyChecked="checkEnable"
:checkIdList="checkIdList"
:chkboxType="{ 'Y': '', 'N': '' }"
:loading="loading.loadData"
:initNotCheck="initNotCheck"
@treeOnCheck="handleTreeOnCheck"
@treeDblClick="handleTreeDblClick"
></laws-tree>
</div>
<div class="demo-drawer-footer" v-if="checkEnable">
<el-button
round
class="common-button-primary"
icon="el-icon-check"
type="primary"
:loading="submitLoading"
@click="handleTreeDrawerConfirm">确定
</el-button>
<el-button
round
class="common-button-default"
icon="el-icon-close"
@click="handleTreeDrawerCancel">取消</el-button>
</div>
</el-drawer>
</template>
<script>
import Bus from '@/common/eventHub'
export default {
name: 'RoleUserTree',
props: {
// 抽屉显示状态
visible: {
type: Boolean,
default: false,
},
// 部门id
BM: {
type: String,
default: ''
},
// 角色层级名称
roleName: {
type: String
},
// 角色ID
roleId: {
type: String
},
// 是否启用checkbox(多选)
checkEnable: {
type: Boolean,
default: false
},
// 节点回显数组
checkIdList: {
type: Array,
default: () => {
return []
}
},
// 最多可选择数量
max: {
type: Number
},
// 数量多于最多数量时的提示
maxTips: {
type: String
},
// 最少选择数量
min: {
type: Number
},
// 数量少于最小数量时的提示
minTips: {
type: String
},
initNotCheck: {
type: Boolean,
default: true
},
submitLoading: {
type: Boolean,
default: false
},
title: {
type: String,
default: '人员结构'
}
},
data () {
return {
isVisible: false, // 组件内抽屉重新赋值
zNodes: [], // 人员树
checkedList: [], // 人员多选选中数组
loading: {
loadData: false
}
}
},
methods: {
// 人员双击事件
handleTreeDblClick (treeId, treeNode) {
this.$emit('dblClick', treeNode)
this.isVisible = false
},
// 人员多选事件
handleTreeOnCheck (checkedList) {
this.checkedList = checkedList
},
// 人员多选确定事件
handleTreeDrawerConfirm() {
if (this.min && this.checkedList.length < this.min) {
const tips = this.minTips || '请至少选择' + this.min + '人'
this.$message.warning(tips)
} else if (this.max && this.checkedList.length > this.max) {
const tips = this.maxTips || '最多可选' + this.max + '人'
this.$message.warning(tips)
} else {
this.$emit('confirm', this.checkedList)
this.isVisible = false
}
},
// 抽屉关闭事件
handleTreeDrawerCancel () {
this.isVisible = false
this.checkedList = []
this.$emit('cancel')
},
// 获取选中的部门下子子部门
getDeptChild (pOrgId) {
return new Promise((resolve, reject) => {
this.loading.loadData = true
this.$http.get('sys/org/getChildDept', {
orgId: this.BM || pOrgId
}, {
_this: this
}, res => {
this.loading.loadData = false
if (res.ok) {
// 获取组织与人员完毕,开始组装树结构
let zNodes = []
let treeNodeList = res.data
for (let i = 0; i < treeNodeList.length; i++) {
let zObj = {}
zObj.id = treeNodeList[i].id
zObj.pId = treeNodeList[i].pId
// 该节点为机构
zObj.name = treeNodeList[i].orgName
zObj.icon = 'static/images/dept.png'
zObj.isParent = true
zObj.shotName = treeNodeList[i].shotName
zObj.remarks = treeNodeList[i].remarks
zObj.iconSkin = 'org-dept'
zNodes[i] = zObj
}
resolve(res.data)
}
}, e => {
reject(e)
})
})
},
// 查询指定角色的人员组成树结构
getUserByRole (treeNodeList2, pOrgId, roleIdTwo, roleHierarchyName) {
return new Promise((resolve, reject) => {
this.loading.loadData = true
this.$http.get('sys/role/getRoleAndUserByOrgId', {
orgId: this.BM || pOrgId,
roleHierarchyName: this.roleName || roleHierarchyName,
roleId: this.roleId || roleIdTwo
}, {
_this: this
}, res => {
this.loading.loadData = false
let treeNodeList = []
if (res.ok) {
for (let pId in treeNodeList2) {
for (let i = 0; i < res.data.length; i++) {
if (treeNodeList2[pId].id === res.data[i].orgId) {
treeNodeList.push(treeNodeList2[pId])
break
}
}
}
for (let i = 0; i < res.data.length; i++) {
let obj = {}
for (let key in res.data[i]) {
if (key === 'userId') {
obj.id = res.data[i][key]
} else if (key === 'orgId') {
obj.pId = res.data[i][key]
} else {
obj[key] = res.data[i][key]
}
}
obj.userId = res.data[i].userId || null
obj.roleId = res.data[i].roleId || null
treeNodeList.push(obj)
}
// 获取组织与人员完毕,开始组装树结构
let zNodes = []
for (let i = 0; i < treeNodeList.length; i++) {
let zObj = {}
// 该节点为人员
if (treeNodeList[i].userName) {
zObj.id = treeNodeList[i].id
zObj.pId = treeNodeList[i].pId
if (treeNodeList[i].email) {
if (treeNodeList[i].roleName) {
zObj.name = `${treeNodeList[i].userName}(${treeNodeList[i].email})(${treeNodeList[i].roleName})`
} else {
zObj.name = `${treeNodeList[i].userName}(${treeNodeList[i].email})`
}
} else {
if (treeNodeList[i].roleName) {
zObj.name = `${treeNodeList[i].userName}(${treeNodeList[i].roleName})`
} else {
zObj.name = `${treeNodeList[i].userName}`
}
}
if (treeNodeList[i].roleName) {
zObj.showName = treeNodeList[i].userName + '(' + treeNodeList[i].roleName + ')'
} else {
zObj.showName = treeNodeList[i].userName
}
zObj.icon = 'static/images/user.png'
zObj.iconSkin = 'org-user'
zObj.isParent = false
zObj.orgName = treeNodeList[i].orgName
// zObj.oldname = treeNodeList[i].userName
zObj.roleId = treeNodeList[i].roleId
zObj.roleName = treeNodeList[i].roleName
zObj.userId = treeNodeList[i].userId
zObj.userName = treeNodeList[i].userName
zObj.pOrgId = treeNodeList[i].pOrgId
zObj.userIdAndRoleId = treeNodeList[i].userIdAndRoleId
} else {
zObj.id = treeNodeList[i].id
zObj.pId = treeNodeList[i].pId
// 该节点为机构
zObj.name = treeNodeList[i].orgName
zObj.oldname = treeNodeList[i].orgName
zObj.showName = treeNodeList[i].orgName
zObj.icon = 'static/images/dept.png'
zObj.iconSkin = 'org-dept'
zObj.isParent = true
zObj.isChecked = true
}
// zObj.shotName = treeNodeList[i].shotName
// zObj.remarks = treeNodeList[i].remarks
if (zObj.pId === null && !zObj.isParent) {
zObj.pId = ''
zObj.orgName = '未分配人员'
}
zNodes[i] = zObj
}
this.zNodes = zNodes
resolve(this.zNodes)
}
}, e => {
this.loading.loadData = false
})
})
},
// 请求部门和人员数据
getRoleUserData(pOrgId, roleIdTwo, roleHierarchyName) {
this.getDeptChild(pOrgId).then(treeNodeList => {
this.getUserByRole(treeNodeList, pOrgId, roleIdTwo, roleHierarchyName)
.then(roleUserData => {
Bus.$emit('resRoleUserData', roleUserData)
})
})
}
},
watch: {
visible (val) {
this.isVisible = val
if (val) {
// 请求部门和人员数据
this.getDeptChild().then(treeNodeList => {
this.getUserByRole(treeNodeList)
})
}
},
isVisible (val) {
this.$emit('update:visible', val)
}
},
mounted () {
Bus.$on('getRoleUserData', (pOrgId, roleIdTwo, roleHierarchyName) => this.getRoleUserData(pOrgId, roleIdTwo, roleHierarchyName))
}
}
</script>
@@ -0,0 +1,272 @@
<!-- 可搜索多选框 -->
<template>
<el-dropdown
ref="searchMultipleSelectDropdown"
trigger="click"
class="search-multiple-select"
size="medium"
>
<div
class="search-input-box"
:class="{ 'search-visible ivu-select-visible': visible }"
@click="visibleToggle">
<div class="v-select-selection" :class="{ 'disabled': disabled }">
<div>
<span class="v-select-placeholder" v-if="!selectedList.length">{{ placeholder }}</span>
<el-tag
v-for="val in selectedList"
:key="val"
closable
:fade="false"
@click.native="visibleToggle"
@on-close="handleRemove(val)">{{ getLabel(val) }}</el-tag>
<i class="el-icon-arrow-down"></i>
</div>
</div>
</div>
<el-dropdown-menu slot="dropdown" class="search-select-el-dropdown-menu">
<div class="search-input">
<el-input
v-model="searchKey"
placeholder="要搜索的内容"
class="input-color"
type="text"></el-input>
</div>
<div class="search-options">
<el-dropdown-item
v-for="option in filterOptions"
:class="[{'ivu-select-item-selected': isSelected(option.value), 'ivu-select-item-focus': focusItem === option.value}]"
:name="option.value || option.id"
:key="option.value"
@click.native="handleOptionClick(option.value)"
>
{{ option.label || option.name }}
</el-dropdown-item>
</div>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
export default {
name: 'searchMultipleSelect',
data () {
return {
// 选择的value
selectedList: [],
visible: false,
// 原始选项数据
filterOptions: [],
// 选项匹配词
searchKey: '',
// 当前点击项
focusItem: ''
}
},
methods: {
/**
* @description: 切换显示状态
* @author: chenxiaoxi
* @date: 2018/12/25 10:38:54
*/
visibleToggle () {
if (!this.disabled) {
this.visible = !this.visible
}
},
/**
* @description: 选取
* @author: chenxiaoxi
* @date: 2018/12/25 10:39:08
*/
handleOptionClick (val) {
if (this.options !== '' && this.options !== null) {
this.options.map((opt) => {
// 用value去匹配label,输入框最终显示的是label
if (opt.value === val) {
let index = this.selectedList.indexOf(val)
if (index === -1) {
this.selectedList.push(val)
} else {
this.selectedList.splice(index, 1)
}
this.focusItem = val
this.$emit('input', this.selectedList)
this.$emit('on-change', this.selectedList)
}
})
}
},
/**
* @description: 选项过滤
* @author: chenxiaoxi
* @date: 2018/12/25 10:44:38
*/
handleFilterOptions () {
// 匹配项来源
if (this.searchKey === '') {
this.filterOptions = this.options
} else {
let result = []
// 用原始数据进行匹配
if (this.options !== '' && this.options !== null) {
this.options.map((opt) => {
if (opt.label.toLowerCase().indexOf(this.searchKey.toLowerCase()) !== -1) {
result.push(opt)
}
})
}
this.filterOptions = result
}
this.$nextTick(() => {
let top = $('.search-multiple-select .ivu-select-dropdown').css('top')
if (top.indexOf('px') > -1) {
top = parseInt(top.substring(0, top.indexOf('p')))
}
if (top > 0) {
$('.search-multiple-select .ivu-select-dropdown').css('top', $('.ivu-dropdown-rel').height())
} else {
$('.search-multiple-select .ivu-select-dropdown').css('top', -$('.search-multiple-select .ivu-select-dropdown').height() - 20)
}
})
},
/**
* @description: 对v-model绑定的值进行匹配
* @author: chenxiaoxi
* @date: 2018/12/25 15:23:46
*/
handleValue () {
if (this.value && this.value !== null && this.value !== '' && this.value.length && this.value[0] !== '') {
this.selectedList = this.value
} else {
this.selectedList = []
}
},
/**
* @description: 当前选项是否被选中
* @author: chenxiaoxi
* @date: 2019/02/25 11:52:00
*/
isSelected (val) {
return this.selectedList.indexOf(val) !== -1
},
/**
* @description: 根据选项值获取选项名
* @author: chenxiaoxi
* @date: 2019/02/25 14:16:07
*/
getLabel (val) {
let label = ''
this.options.map((opt) => {
if (opt.value === val) {
label = opt.label
}
})
return label
},
/**
* @description: 选项移除
* @author: chenxiaoxi
* @date: 2019/02/25 14:21:01
*/
handleRemove (val) {
if (!this.disabled) {
this.selectedList.splice(this.selectedList.indexOf(val), 1)
}
}
},
components: {},
props: {
value: {
type: [String, Array]
},
options: {
required: true
},
placeholder: {
type: String,
default: '请选择'
},
disabled: {
type: Boolean,
default: false
}
},
computed: {},
watch: {
// 监听显示状态
visible (val) {
if (val) {
// 当显示的时候,给选项框外绑定事件
window.addEventListener('click', function (e) {
// 点击的是搜索框外
if ($(e.target).parents('.search-multiple-select').length === 0) {
this.visible = false
}
}.bind(this))
} else {
this.searchKey = ''
}
},
// 监听关键词的变化,代替keyup事件
searchKey (val) {
this.handleFilterOptions()
},
// 监听v-model变化
value (val) {
this.handleValue()
},
// 监听options变化
options (val, oldVal) {
this.filterOptions = JSON.parse(JSON.stringify(this.options))
this.handleValue()
},
// 修改定位
selectedList (val) {
if (val.length) {
this.handleValue()
}
}
},
mounted () {
this.handleValue()
this.filterOptions = JSON.parse(JSON.stringify(this.options))
}
}
</script>
<style lang="less">
@import '~@/assets/styles/mixins';
@import '~@/assets/styles/style';
.search-multiple-select{
.el-icon-arrow-down:before {
float: right;
}
.v-select-selection{
padding: 0 24px 0 4px;
&.disabled{
background-color: #f3f3f3;
opacity: 1;
cursor: not-allowed;
color: #ccc;
.ivu-tag{
background-color: #f2f2f2;
cursor: not-allowed;
}
}
.ivu-tag{
height: 24px;
line-height: 22px;
margin: 3px 4px 3px 0;
max-width: 99%;
position: relative;
}
}
}
</style>
+205
View File
@@ -0,0 +1,205 @@
<!-- 可搜索选择框 -->
<template>
<el-dropdown
trigger="click"
class="search-select"
size="medium"
>
<el-input
type="text"
readonly
:placeholder="placeholder"
v-model="selectedLabel"
suffix-icon="el-icon-arrow-down"
@click.native="visibleToggle"
:class="{ 'search-visible': visible }"
></el-input>
<el-input
type="hidden"
v-model="selectedValue"
class="el-input-hidden"
></el-input>
<el-dropdown-menu
slot="dropdown"
class="search-select-el-dropdown-menu"
>
<div class="search-input">
<el-input
v-model="searchKey"
placeholder="要搜索的内容"
class="input-color"
clearable />
</div>
<div class="search-options">
<el-dropdown-item
v-for="option in filterOptions"
:name="option.value || option.id"
:title="option.label || option.name"
:key="option.value"
:disabled="disabled"
@click.native="ondropClick(option)"
>
{{ option.label || option.name }}
</el-dropdown-item>
</div>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
export default {
name: 'searchSelect',
data () {
return {
// 显示的label
selectedLabel: '',
// 选择的value
selectedValue: '',
visible: false,
// 原始选项数据
filterOptions: [],
// 选项匹配词
searchKey: ''
}
},
methods: {
/**
* @description: 切换显示状态
* @author: chenxiaoxi
* @date: 2018/12/25 10:38:54
*/
visibleToggle () {
if (!this.disabled) {
this.visible = !this.visible
}
},
/**
* @description: 选项过滤
* @author: chenxiaoxi
* @date: 2018/12/25 10:44:38
*/
handleFilterOptions () {
// 匹配项来源
if (this.searchKey === '') {
this.filterOptions = this.options
} else {
let result = []
// 用原始数据进行匹配
if (this.options !== '' && this.options !== null) {
this.options.map((opt) => {
if (opt.label !== null && opt.label.indexOf(this.searchKey) !== -1) {
result.push(opt)
}
})
}
this.filterOptions = result
}
},
/**
* @description: 对v-model绑定的值进行匹配
* @author: chenxiaoxi
* @date: 2018/12/25 15:23:46
*/
handleValue () {
if (this.value && this.value !== '') {
if (this.options !== '' && this.options !== null) {
this.options.map((opt) => {
if (opt.value === this.value || opt.id === this.value) {
this.selectedLabel = opt.label || opt.name
this.selectedValue = opt.value || opt.id
}
})
}
} else {
this.selectedLabel = ''
this.selectedValue = ''
}
},
// 点击下拉选项事件
ondropClick (option) {
this.visible = false // 隐藏下拉菜单
this.selectedValue = option.value
this.selectedLabel = option.label
this.$emit('input', option.value) // 赋值给父组件
this.$emit('on-change', option.value) // 赋值给父组件
}
},
components: {},
props: {
value: {
type: [String, Number]
},
options: {
required: true
},
placeholder: {
type: String,
default: '请选择'
},
disabled: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: true
}
},
computed: {},
watch: {
selectedLabel: {
deep: true,
handler (val, oldVal) {
// 当外层输入框内容清空时, 将selectedValue置为空
if (val === '') {
this.selectedValue = ''
}
}
},
// 监听显示状态
visible (val) {
if (val) {
// 当显示的时候,给选项框外绑定事件
window.addEventListener('click', function (e) {
// 点击的是搜索框外
if ($(e.target).parents('.search-select').length === 0) {
this.visible = false
}
}.bind(this))
} else {
this.searchKey = ''
}
},
// 监听关键词的变化,代替keyup事件
searchKey (val) {
this.handleFilterOptions()
},
// 监听最终选取的值
selectedValue (val) {
if (val === '' || this.selectedLabel === '') {
this.$emit('input', val)
this.$emit('on-change', val)
}
},
// 监听v-model变化
value (val) {
this.handleValue()
},
// 监听options变化
options (val, oldVal) {
this.filterOptions = JSON.parse(JSON.stringify(this.options))
this.handleValue()
}
},
mounted () {
this.filterOptions = JSON.parse(JSON.stringify(this.options))
this.handleValue()
}
}
</script>
<style lang="less">
@import '~@/assets/styles/mixins';
@import '~@/assets/styles/style';
</style>
+151
View File
@@ -0,0 +1,151 @@
<!-- 表格工具栏 -->
<template>
<div class="table-tools-bar">
<transition enter-active-class="animated slideInDown" leave-active-class="animated slideOutUp" :duration="1000">
<div class="advanced-search" v-if="isAdvancedSearch">
<div class="advanced-search-content">
<div class="close-btn" @click="close">&times;</div>
<slot name="content"></slot>
</div>
<div class="advanced-search-footer">
<el-button icon="el-icon-search"
type="primary"
class="common-button-primary"
round @click="advancedSearch" style="margin-right: 5px" >{{$t('m.advancedSearch')}}</el-button>
<el-button @click="reset"
class="common-button-default"
icon="el-icon-refresh-left"
round></el-button>
</div>
</div>
</transition>
<div class="tools-bar-wrapper">
<slot name="left"></slot>
<slot name="right"></slot>
</div>
<!--<el-divider />-->
</div>
</template>
<script>
export default {
name: 'table-tools-bar',
data () {
return {
isAdvancedSearch: this.value
}
},
methods: {
// 重置
reset () {
this.$emit('reset')
},
// 高级搜索
advancedSearch () {
this.$emit('search')
this.$emit('input', false)
},
// 关闭
close () {
this.$emit('toggleSearch')
this.$emit('input', false)
}
},
props: {
// 是否为高级搜索
value: {
type: Boolean,
default: false
}
},
watch: {
value (val) {
this.isAdvancedSearch = val
},
'$route': {
deep: true,
handler (val) {
if (val) {
this.$emit('input', false)
}
}
}
}
}
</script>
<style lang="less">
@import '~@/assets/styles/mixins';
@import '~@/assets/styles/style';
.table-tools-bar{
background: #fff;
.search-area {
margin-bottom: 0 !important;
}
.advanced-search{
width: 100%;
position: absolute;
top: 0;
left: 0;
background: rgba(255,255,255,.95);
border-bottom: 1px solid #DDD;
z-index: 100;
.advanced-search-content{
width: 100%;
position: relative;
padding: 30px 30px 15px 15px;
.close-btn{
line-height: 40px;
font-size: 40px;
text-align: center;
position: absolute;
top: 5px;
right: 10px;
z-index: 100;
&:hover{
color: @baseColor;
cursor: pointer;
}
}
}
.advanced-search-footer{
width: 100%;
padding: 8px 20px;
.flex();
justify-content: flex-end;
}
}
.tools-bar-wrapper{
display: flex;
justify-content: space-between;
align-items: center;
/*margin-bottom: 0.1rem;*/
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
/*padding-top: 0.1rem;*/
&>div{
&>div{
display: inline-block;
}
}
& > div:first-child{
& > span{
display: inline-block;
width: 700px;
.ellipsis();
}
}
.label-select-content{
min-width: 150px;
/*width: auto !important;*/
}
.label-input-content{
min-width: 150px;
/*width: auto !important;*/
}
}
}
</style>
+94
View File
@@ -0,0 +1,94 @@
<!-- UEditor -->
<template>
<div>
<script id="editor" type="text/plain" ></script>
</div>
</template>
<script>
/* eslint-disable */
// import 'ueditor/example/public/ueditor/ueditor.config'
// import 'ueditor/example/public/ueditor/ueditor.all'
// import 'ueditor/example/public/ueditor/lang/zh-cn/zh-cn'
import '@/../public/static/ueditor/ueditor.config.js'
import '@/../public/static/ueditor/ueditor.all.js'
import '@/../public/static/ueditor/lang/zh-cn/zh-cn.js'
export default {
name: 'UEditor',
data () {
return {
editor: null
}
},
methods: {
getUEContent: function () {
return this.editor.getContent()
},
getContentTxt: function () {
return this.editor.getContentTxt()
},
setContent (content) {
// return this.editor.setContent(content)
this.editor.ready(() => {
this.editor.setContent(content);
})
},
getContentLength () {
return this.editor.getContentLength()
}
},
props: {
id: {
type: String
},
config: {
type: Object
},
fontfamily: {
type: String,
default: ''
},
fontsize: {
type: String,
default: ''
},
bold: {
type: Boolean,
default: false
},
content:{
type: String,
default: ''
}
},
watch: {
},
mounted () {
// 初始化UE
this.editor = UE.delEditor('editor')
this.editor = UE.getEditor('editor', this.config)
let _this = this
UE.getEditor('editor').addListener('blur',function(editor){
_this.$emit('editor-onChange', _this.getUEContent())
});
UE.getEditor('editor').ready(function() {
if (_this.fontfamily !== '') {
UE.getEditor('editor').execCommand( 'fontfamily',_this.fontfamily)
}
if (_this.content !== '') {
UE.getEditor('editor').setContent(_this.content)
}
if (_this.fontsize !== '') {
UE.getEditor('editor').execCommand( 'fontsize', _this.fontsize )
}
if (_this.bold) {
UE.getEditor('editor').execCommand('bold')
}
});
},
destoryed () {
this.editor.destory()
}
}
</script>