Files
structureplugins/jero-web/src/views/documentTool/documentSplit/modules/SplitAddForm.vue
T

645 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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()">{{ $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 v-else-if="clause.type === TypeOfClauseItem.IMG.value">
<img :src="clause.thumbUrl?clause.thumbUrl:clause.itemContent"
alt="">
</viewer>
<!--表格-->
<div v-else-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,
isTopList: 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 => {
if (item.type === this.TypeOfClauseItem.TABLE.value) {
item.itemContent = window.getHtml(item.itemContent)
}
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.isTopList = false
this.addIndex = this.contentList.length - 1
} else if (!index) {
this.isTopList = true
this.addIndex = this.contentList.length - 1
} else {
this.addIndex = index
this.isTopList = false
}
this.$refs.splitDetailAddTypeCheck.open()
},
// 增加条款内容成功
handleAddOk (type, content) {
let headerArr = []
let footerArr = []
if (this.isTopList) {
headerArr = this.contentList
footerArr = []
} else {
headerArr = this.contentList.splice(0, this.addIndex + 1)
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]
console.log(this.contentList)
},
/**
* 表格编辑
* @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>