629 lines
16 KiB
Vue
629 lines
16 KiB
Vue
<template>
|
||
<a-drawer
|
||
:title="title"
|
||
placement="right"
|
||
:visible="visible"
|
||
@close="handleCancel"
|
||
width="900"
|
||
class="custom-drawer-style">
|
||
|
||
<div class="custom-drawer-style-scroll">
|
||
<a-spin :spinning="loading">
|
||
<!--表单部分-->
|
||
<a-form-model :model="formInline" class="form-add" :rules="rules" ref="ruleForm">
|
||
<div class="form-flex-box">
|
||
<div class="box-title-text form-flex-item">
|
||
<div class="title-text">
|
||
<span class="required">*</span>
|
||
<span class="title-text-text" :title="$t('docTool.split.clauseNo')">{{ $t('docTool.split.clauseNo') }}</span>
|
||
</div>
|
||
<a-form-model-item class="item-model" :prop="'item_num'">
|
||
<a-input class="box-input"
|
||
:disabled="disabled"
|
||
v-model="formInline.item_num"
|
||
:maxLength="50"
|
||
@change="event => event.target.value = event.target.value.trim()"
|
||
:placeholder="$t('pleaseEnter')+$t('docTool.split.clauseNo')"/>
|
||
</a-form-model-item>
|
||
</div>
|
||
|
||
<div class="box-title-text form-flex-item">
|
||
<div class="title-text">
|
||
<span class="title-text-text" :title="$t('docTool.split.clauseName')">{{ $t('docTool.split.clauseName') }}</span>
|
||
</div>
|
||
<a-form-model-item class="item-model">
|
||
<a-input class="box-input"
|
||
:disabled="disabled"
|
||
v-model="formInline.item_title"
|
||
:maxLength="2000"
|
||
@change="event => event.target.value = event.target.value.trim()"
|
||
:placeholder="$t('pleaseEnter')+$t('docTool.split.clauseName')"/>
|
||
</a-form-model-item>
|
||
</div>
|
||
</div>
|
||
<upload-file ref="uploadFile" @change="uploadFileChange" :return-url="false"></upload-file>
|
||
</a-form-model>
|
||
|
||
<!--条款内容部分-->
|
||
<div class="header-text">
|
||
{{ $t('docTool.split.clauseContent') }}
|
||
<!--新增条款项-->
|
||
<a-button type="primary" icon="plus" ghost @click="handleAddClauseContent(1)">{{ $t('newlyAdded') }}</a-button>
|
||
</div>
|
||
<template v-if="contentList && contentList.length > 0">
|
||
<div class="clause-item" v-for="(clause, index) in contentList" :key="index + 'clause'">
|
||
<div class="clause-item-content">
|
||
<!--文本-->
|
||
<a-input type="textarea"
|
||
:maxLength="500"
|
||
v-model="clause.itemContent"
|
||
v-if="clause.type === TypeOfClauseItem.TEXT.value" />
|
||
<!--图片-->
|
||
<viewer>
|
||
<img v-if="clause.type === TypeOfClauseItem.IMG.value"
|
||
:src="clause.thumbUrl?clause.thumbUrl:clause.itemContent"
|
||
alt="">
|
||
</viewer>
|
||
<!--表格-->
|
||
<div v-if="clause.type === TypeOfClauseItem.TABLE.value" v-html="clause.itemContent"></div>
|
||
</div>
|
||
<div class="clause-item-operate">
|
||
<a-button @click="handleAddClauseContent(index)">{{ $t('newlyAdded') }}</a-button>
|
||
<a-button v-if="clause.type === TypeOfClauseItem.TABLE.value" @click="splitEdit(index,clause)">{{
|
||
$t('edit')
|
||
}}
|
||
</a-button>
|
||
<a-button @click="handleDeleteClauseContent(index, clause)">{{ $t('delete') }}</a-button>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</a-spin>
|
||
</div>
|
||
<div class="custom-drawer-style-bottom-btn">
|
||
<a-button @click="handleCancel">{{ $t('cancel') }}</a-button>
|
||
<a-button type="primary" class="footer-btn-save" @click="handleSave">{{ $t('preservation') }}</a-button>
|
||
</div>
|
||
|
||
<!-- 类型选择弹框 -->
|
||
<split-detail-add-type-check ref="splitDetailAddTypeCheck" @ok="handleAddOk" />
|
||
<!-- 编辑表格弹框 -->
|
||
<split-detail-add-table ref="splitDetailAddTable" @editOk="editTableOk" />
|
||
</a-drawer>
|
||
</template>
|
||
|
||
<script>
|
||
import UploadFile from '../../../../components/UploadFile.vue'
|
||
// 类型选择弹框
|
||
import SplitDetailAddTypeCheck from './SplitDetailAddTypeCheck.vue'
|
||
import SplitDetailAddTable from './SplitDetailAddTable.vue'
|
||
import {
|
||
addClause,
|
||
editClause,
|
||
getEditClauseContent
|
||
} from '../../../../api/documentToolApi.js'
|
||
import { ClauseUsableRange, FieldType, TypeOfClauseItem, YesOrNoEnum } from '../../../../enums/commonEnums'
|
||
|
||
export default {
|
||
name: 'SplitAddForm',
|
||
components: {
|
||
SplitDetailAddTable,
|
||
UploadFile,
|
||
SplitDetailAddTypeCheck,
|
||
},
|
||
data () {
|
||
return {
|
||
FieldType,
|
||
TypeOfClauseItem,
|
||
hiddenFieldList: ['item_content'], // 隐藏的字段
|
||
radioDictSelect: ['is_long_effect'], // 使用radio样式的数据字典单选
|
||
disabledFieldList: [], // 禁用的字段
|
||
specialPlaceholder: {}, // 特殊的placeholder
|
||
optionsData: {}, // 通过接口获取的下拉数据
|
||
title: this.$t('newlyAdded'),
|
||
contentList: [], // 条款内容数据
|
||
visible: false,
|
||
addIndex: 0, // 新增条款的index
|
||
disabled: false,
|
||
formInline: {},
|
||
isFormInline: false,
|
||
dataList: [],
|
||
ruleList: [],
|
||
rules: {
|
||
item_num: [
|
||
{
|
||
required: true,
|
||
message: this.$t('docTool.split.clauseNo') + this.$t('cannotEmpty'),
|
||
trigger: 'blur'
|
||
}
|
||
]
|
||
},
|
||
uploadName: '',
|
||
type: 'add',
|
||
loading: false,
|
||
submitFlag: false,
|
||
deleteIds: [],
|
||
itemVal: {},
|
||
contentTrees: '',
|
||
isTableEdit: false,
|
||
}
|
||
},
|
||
props: {
|
||
flag: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
infoId: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
menuId: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
itemId: {
|
||
type: String,
|
||
default: ''
|
||
}
|
||
},
|
||
watch: {},
|
||
methods: {
|
||
/**
|
||
* 新增
|
||
*/
|
||
add () {
|
||
this.visible = true
|
||
this.formInline = {}
|
||
this.contentList = []
|
||
this.type = 'add'
|
||
},
|
||
/**
|
||
* 编辑
|
||
* @param item
|
||
*/
|
||
edit (item) {
|
||
this.visible = true
|
||
this.type = 'edit'
|
||
this.itemVal = item
|
||
this.formInline = { ...item }
|
||
this.getClauseContentList()
|
||
},
|
||
|
||
/**
|
||
* 获取条款内容列表
|
||
*/
|
||
getClauseContentList () {
|
||
this.loading = true
|
||
getEditClauseContent({ id: this.itemVal.id }).then(res => {
|
||
if (res.success) {
|
||
this.contentList = [...res.result]
|
||
this.contentList.forEach(item => {
|
||
const imgData = item.itemContent.split('fileName=')[1]
|
||
item.thumbUrl = window._CONFIG.domianURL + '/sys/split/file/getImage?fileName=' + imgData
|
||
})
|
||
}
|
||
}).finally(() => {
|
||
this.loading = false
|
||
})
|
||
},
|
||
/**
|
||
* 新增条款内容
|
||
* @param index
|
||
*/
|
||
handleAddClauseContent (index) {
|
||
if (index === -1) {
|
||
this.addIndex = this.contentList.length - 1
|
||
} else {
|
||
this.addIndex = index
|
||
}
|
||
this.$refs.splitDetailAddTypeCheck.open()
|
||
},
|
||
// 增加条款内容成功
|
||
handleAddOk (type, content) {
|
||
const headerArr = this.contentList.splice(0, this.addIndex + 1)
|
||
const footerArr = this.contentList.splice(-this.addIndex)
|
||
const insertArr = []
|
||
switch (type) {
|
||
case TypeOfClauseItem.TEXT.value:
|
||
for (let i = 0; i < content; i++) {
|
||
insertArr.push({
|
||
id: '',
|
||
type: TypeOfClauseItem.TEXT.value,
|
||
itemContent: ''
|
||
})
|
||
}
|
||
break
|
||
case TypeOfClauseItem.IMG.value:
|
||
insertArr[0] = {
|
||
id: '',
|
||
type: TypeOfClauseItem.IMG.value,
|
||
itemContent: content.file.response.result.url,
|
||
thumbUrl: window._CONFIG.domianURL + '/sys/split/file/getImage?fileName=' + content.file.response.result.url.split('fileName=')[1]
|
||
}
|
||
break
|
||
case TypeOfClauseItem.TABLE.value:
|
||
insertArr[0] = {
|
||
id: '',
|
||
type: 'TABLE',
|
||
itemContent: content[0]
|
||
}
|
||
}
|
||
this.contentList = [...headerArr, ...insertArr, ...footerArr]
|
||
},
|
||
/**
|
||
* 表格编辑
|
||
* @param index
|
||
* @param item
|
||
*/
|
||
splitEdit (index, item) {
|
||
this.addIndex = index
|
||
this.$refs.splitDetailAddTable.open(item.itemContent)
|
||
this.$refs.splitDetailAddTable.isTableEdit = true
|
||
},
|
||
/**
|
||
* 编辑表格类型成功
|
||
* @param ueContent
|
||
*/
|
||
editTableOk (ueContent) {
|
||
this.contentList[this.addIndex] = {
|
||
id: '',
|
||
type: 'TABLE',
|
||
itemContent: ueContent[0]
|
||
}
|
||
this.contentList = JSON.parse(JSON.stringify(this.contentList))
|
||
},
|
||
// 点击点击上传按钮
|
||
clickButtonToUpload (item) {
|
||
this.$refs.uploadFile.open(this.formInline[item.dbFieldName])
|
||
this.uploadName = item.dbFieldName
|
||
},
|
||
// 文件上传改变后的回调
|
||
uploadFileChange (data) {
|
||
const attIdList = []
|
||
if (data && data.length > 0) {
|
||
data.map(item => {
|
||
attIdList.push(item.id || data.name)
|
||
})
|
||
}
|
||
/** 赋值给当前对应的表单文件 */
|
||
this.formInline[this.uploadName] = attIdList.join(',')
|
||
this.formInline = { ...this.formInline }
|
||
},
|
||
// 正则替换小数点
|
||
limitNumber (value) {
|
||
if (typeof value === 'string') {
|
||
return !isNaN(Number(value)) ? value.replace(/\./g, '') : 0
|
||
} else if (typeof value === 'number') {
|
||
return !isNaN(value) ? String(value).replace(/\./g, '') : 0
|
||
} else {
|
||
return 0
|
||
}
|
||
},
|
||
/**
|
||
* 删除条款内容
|
||
* @param index
|
||
* @param clause
|
||
*/
|
||
handleDeleteClauseContent (index, clause) {
|
||
this.contentList.splice(index, 1)
|
||
if (clause.id) {
|
||
this.deleteIds.push(clause.id)
|
||
}
|
||
},
|
||
handleCancel () {
|
||
this.close()
|
||
},
|
||
close () {
|
||
this.visible = false
|
||
this.formInline = {}
|
||
this.contentList = []
|
||
},
|
||
handleSave () {
|
||
if (this.submitFlag) {
|
||
return
|
||
}
|
||
this.$refs.ruleForm.validate(valid => {
|
||
if (valid) {
|
||
this.submitFlag = true
|
||
this.loading = true
|
||
// 判断新增编辑
|
||
let submitFunc
|
||
if (this.formInline.id) {
|
||
submitFunc = editClause
|
||
} else {
|
||
submitFunc = addClause
|
||
}
|
||
// 处理请求参数
|
||
const formData = JSON.parse(JSON.stringify(this.formInline))
|
||
// 处理动态表单多选的值
|
||
Object.keys(formData).forEach(res => {
|
||
if (formData[res] instanceof Array) {
|
||
if (formData[res][0] instanceof Object) {
|
||
// 说明是树选择
|
||
formData[res] = formData[res].map(item => item.value).join(',')
|
||
} else {
|
||
formData[res] = formData[res].join(',')
|
||
}
|
||
}
|
||
})
|
||
formData.info_id = this.infoId
|
||
formData.menu_id = this.menuId
|
||
const contentList = JSON.parse(JSON.stringify(this.contentList))
|
||
contentList.forEach((item, index) => {
|
||
if (item.type === 'IMG') {
|
||
delete item.thumbUrl
|
||
}
|
||
})
|
||
formData.itemValEOList = contentList
|
||
formData.delItemIds = this.deleteIds.join(',')
|
||
submitFunc(formData).then(res => {
|
||
if (res.success) {
|
||
this.$message.success(res.message)
|
||
this.$emit('ok')
|
||
this.close()
|
||
} else {
|
||
this.$message.warning(res.message)
|
||
}
|
||
}).finally(() => {
|
||
this.loading = false
|
||
this.submitFlag = false
|
||
})
|
||
}
|
||
})
|
||
},
|
||
updateDom () {
|
||
this.$forceUpdate()
|
||
},
|
||
filterTreeOption (input, option) {
|
||
const text = option.componentOptions.propsData.title || option.componentOptions.propsData.label
|
||
return text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||
},
|
||
/**
|
||
* 属性标识的子集字段处理
|
||
* @param field
|
||
* @returns {null|string}
|
||
*/
|
||
getTreeSelectionChildrenColumnName (field) {
|
||
if (field.dbFieldName === 'property_tag') {
|
||
return 'childrenList'
|
||
}
|
||
return null
|
||
},
|
||
/**
|
||
* 如果字段中的usableRange只有一个值,那么就需要在placeholder中标识
|
||
* @param field
|
||
*/
|
||
getPlaceholderSuffix (field) {
|
||
const fieldUsableRange = (field.usableRange || '').split(',')
|
||
if (fieldUsableRange.length === 1) {
|
||
return `(${ClauseUsableRange.nameOfIndex(fieldUsableRange[0])})`
|
||
}
|
||
return ''
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="less">
|
||
.split-content {
|
||
.box-title-text {
|
||
line-height: 1.4;
|
||
display: flex;
|
||
|
||
.title-text {
|
||
width: 114px;
|
||
text-align: right;
|
||
display: inline-block;
|
||
font-weight: 500;
|
||
font-size: 14px;
|
||
margin-right: 16px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
height: 42px;
|
||
line-height: 42px;
|
||
|
||
.Required {
|
||
color: red;
|
||
margin-right: 4px;
|
||
}
|
||
|
||
.title-text-text {
|
||
margin-top: 9px;
|
||
}
|
||
}
|
||
|
||
.item-model {
|
||
width: calc(100% - 130px);
|
||
display: inline-block;
|
||
margin-top: 2px;
|
||
}
|
||
|
||
}
|
||
|
||
.con-divider {
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
color: rgba(0, 0, 0, 0.85)
|
||
}
|
||
|
||
.table-operator {
|
||
margin-bottom: 20px;
|
||
text-align: right;
|
||
}
|
||
|
||
}
|
||
|
||
.split-content-row {
|
||
.split-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin: 0 20px 20px;
|
||
|
||
.row-left {
|
||
flex: 1;
|
||
|
||
/*border:1px solid #9e9e9e;*/
|
||
|
||
img {
|
||
cursor: pointer;
|
||
width: 32px;
|
||
height: 32px;
|
||
}
|
||
|
||
.item-table {
|
||
/deep/ table {
|
||
width: 100% !important;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
.row-right {
|
||
min-width: 150px;
|
||
margin-left: 20px;
|
||
|
||
.row-btn-add, .row-btn-edit {
|
||
margin-right: 20px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.split-form-footer {
|
||
margin-top: 20px;
|
||
text-align: center;
|
||
position: fixed;
|
||
bottom: 0px;
|
||
right: 0;
|
||
width: 900px;
|
||
padding-bottom: 10px;
|
||
background: #FFFFFF;
|
||
|
||
.footer-btn-save {
|
||
margin-right: 20px;
|
||
}
|
||
}
|
||
|
||
.split-title {
|
||
.title-wraper {
|
||
.title-top {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
|
||
.title-flex {
|
||
width: 75px;
|
||
height: 35px;
|
||
text-align: center;
|
||
border-radius: 5px;
|
||
border: 1px solid #d9d9d9;
|
||
padding: 7px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.title-flex-active {
|
||
background: #00B3BE;
|
||
border-color: #00B3BE;
|
||
color: #FFFFFF;
|
||
}
|
||
}
|
||
|
||
.title-num {
|
||
margin: 20px 20px 0;
|
||
line-height: 32px;
|
||
|
||
.title-num-add {
|
||
min-width: 70px;
|
||
}
|
||
|
||
.title-num-edit {
|
||
flex: 1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.split-img {
|
||
margin-top: 20px;
|
||
text-align: center;
|
||
|
||
img {
|
||
}
|
||
}
|
||
|
||
/*用到的css代码*/
|
||
.form-flex-box {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.form-flex-item {
|
||
width: 100%;
|
||
}
|
||
|
||
.header-text {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.clause-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin: 0 0 20px 20px;
|
||
|
||
&-content {
|
||
width: 0;
|
||
flex: 1;
|
||
|
||
/deep/ table {
|
||
width: 100%;
|
||
}
|
||
|
||
/deep/ img {
|
||
max-width: 100%;
|
||
max-height: 500px;
|
||
}
|
||
}
|
||
|
||
&-operate {
|
||
|
||
.ant-btn {
|
||
margin-left: 15px
|
||
}
|
||
}
|
||
}
|
||
|
||
.clause-item:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
/deep/ .ant-select-tree-dropdown {
|
||
max-height: 50vh !important;
|
||
}
|
||
|
||
.unscramble-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: 20px;
|
||
|
||
&-content {
|
||
width: 0;
|
||
flex: 1;
|
||
}
|
||
|
||
&-operate {
|
||
|
||
.ant-btn {
|
||
margin-left: 15px
|
||
}
|
||
}
|
||
}
|
||
|
||
.unscramble-item:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
/deep/ .clause-item-content td, th{
|
||
border: 1px solid #DDD;
|
||
}
|
||
</style>
|