123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772 |
- <template>
- <view class="uni-app">
- <view class="status-bar" />
- <view class="main-container">
- <wk-nav-bar :title="navTitle">
- <!-- #ifndef MP-WEIXIN -->
- <button class="button white-btn" @click="handleSave">
- 保存
- </button>
- <!-- #endif -->
- </wk-nav-bar>
- <view class="container">
- <view class="scroll-content">
- <wk-form
- v-if="fieldArr.length > 0"
- ref="form"
- :batch-id="batchId"
- :fields="fieldArr"
- @change="handleValueChange" />
- <view v-if="showCauseForm" class="travel">
- <add-travel
- v-for="(item, c_index) in causeList"
- ref="addTravel"
- :key="c_index"
- :index="c_index"
- :length="causeList.length"
- :type="causeType"
- :item-data="item"
- @change="handleChangeTravel"
- @delete="handleDeleteTravel" />
- <view class="travel-item-footer">
- <text class="wk wk-plus add-icon" />
- <text @click="handleAddTravel">
- 添加明细
- </text>
- </view>
- </view>
- <wk-form
- v-if="fieldArr2.length > 0"
- ref="form2"
- :batch-id="batchId"
- :fields="fieldArr2"
- @change="handleValueChange" />
- <view class="attachment">
- <!--图片-->
- <view class="attachment-box">
- <view class="attachment-title" @click.stop="addFile('img')">
- <view class="left">
- <image :src="$static('images/icon/image.png')" class="pic-icon" />
- 图片
- </view>
- <view class="right add-icon">
- <text class="wk wk-plus" />
- </view>
- </view>
- <wk-image-content
- show-delete
- :list="imgList"
- @delete="handleDeleteImg" />
- </view>
- <!--附件-->
- <view class="attachment-box">
- <view class="attachment-title" @click.stop="addFile('file')">
- <view class="left">
- <image :src="$static('images/icon/clip.png')" class="pic-icon" />
- 附件
- </view>
- <view class="right add-icon">
- <text class="wk wk-plus" />
- </view>
- </view>
- <wk-file-content
- show-delete
- :list="fileList"
- @delete="handleDeleteFile" />
- </view>
- <!--关联业务-->
- <view class="attachment-box">
- <view class="attachment-title" @click.stop="getRelevancePopOptions">
- <view class="left">
- <image :src="$static('images/icon/relate.png')" class="pic-icon" />
- 关联业务
- </view>
- <view class="right add-icon">
- <text class="wk wk-plus" />
- </view>
- </view>
- <relevance-section
- v-if="showRelevance"
- is-add
- :relevance-data="relevanceData"
- @delete="baseDelete" />
- </view>
- </view>
- <wk-audit-add ref="wkAuditAdd" />
- </view>
- </view>
- <!-- #ifdef MP-WEIXIN -->
- <view class="footer-btn-group">
- <button class="button" @click="handleSave">
- 保存
- </button>
- </view>
- <!-- #endif -->
- </view>
- <uni-popup ref="popup">
- <view class="pop-wrapper">
- <view
- v-for="(item, index) in popOptions"
- :key="index"
- class="pop-item"
- @click.stop="handleSelectOptions(item)">
- {{ item.label }}
- </view>
- </view>
- </uni-popup>
- </view>
- </template>
- <script>
- import {
- SetOaExamine,
- QueryExamineInfo,
- GetField,
- QueryField
- } from 'API/oa/examine'
- import { FileDeleteById } from 'API/file'
- import { PreviewFiledName } from 'API/examine'
- import RelevanceSection from '@/components/base/relevance-section.vue'
- import AddTravel from './components/addTravel'
- import formMixins from '@/mixins/formMixins.js'
- import WkFile from '@/utils/file.js'
- import { addOperation } from '@/utils/lib.js'
- export default {
- name: 'AddOaExamine',
- components: {
- RelevanceSection,
- AddTravel
- },
- mixins: [formMixins],
- data() {
- return {
- guid: null,
- id: null,
- examineId: null,
- routerQuery: {},
- fieldArr: [],
- fieldArr2: [],
- batchId: null,
- fileList: [],
- imgList: [],
- popOptions: [],
- causeList: [],
- showCauseForm: false,
- causeType: null,
- auditConditionFields: [],
- timer: null,
- customerList: [],
- contactsList: [],
- businessList: [],
- contractList: [],
- }
- },
- computed: {
- navTitle() {
- if (this.id) return `编辑${this.routerQuery.title}`
- else return `新建${this.routerQuery.title}`
- },
- showRelevance() {
- return this.customerList.length > 0 ||
- this.contactsList.length > 0 ||
- this.businessList.length > 0 ||
- this.contractList.length > 0
- },
- relevanceData() {
- return {
- customerList: this.customerList || [],
- contactsList: this.contactsList || [],
- businessList: this.businessList || [],
- contractList: this.contractList || [],
- }
- }
- },
- watch: {
- causeList: {
- handler(val) {
- const that = this
- let total = 0
- console.log('change case: ', val)
- if (that.causeType === 'travel') {
- // 自动计算出差总天数
- that.causeList.forEach(cause => {
- if (cause.hasOwnProperty('duration') && !that.$isEmpty(cause.duration)) {
- let v = isNaN(cause.duration) ? 0 : Number(cause.duration)
- console.log('vv:', v)
- total = addOperation(total, v)
- }
- })
- that.$nextTick(function() {
- that.$refs.form.setFormVal('duration', total)
- if (that.fieldArr2.length > 0) {
- that.$refs.form2.setFormVal('duration', total)
- }
- })
- } else if (that.causeType === 'examine') {
- // 自动计算差旅报销总金额
- let arr = ['traffic', 'stay', 'diet', 'other']
- that.causeList.forEach(cause => {
- if (!that.$isEmpty(cause)) {
- arr.forEach(item => {
- if (cause.hasOwnProperty(item) && !that.$isEmpty(cause[item])) {
- let v = isNaN(Number(cause[item])) ? 0 : Number(cause[item])
- total = addOperation(total, v)
- }
- })
- }
- })
- that.$nextTick(function() {
- that.$refs.form.setFormVal('money', total)
- if (that.fieldArr2.length > 0) {
- that.$refs.form2.setFormVal('money', total)
- }
- })
- }
- },
- deep: true
- }
- },
- created() {
- this.guid = this.$guid()
- },
- onLoad(options) {
- this.routerQuery = options || {}
- this.examineId = this.routerQuery.examineId || null // 审批类型id
- this.id = this.routerQuery.id || null // 审批id
- this.getData()
- },
- onUnload() {
- getApp().globalData.selectedValBridge = {}
- },
- methods: {
- /**
- * 通过id获取审批详情, 和自定义字段数据
- */
- getData() {
- let list = []
- if (this.id) {
- list = [
- GetField({examineId: this.id, isDetail: 2, label: 10, id: this.examineId, type: 1 }),
- QueryExamineInfo({ examineId: this.id }),
- ]
- } else {
- list = [
- QueryField({ examineId: this.examineId, type: 1 })
- ]
- }
- Promise.all(list).then(res => {
- // this.fieldArr = this.formatFieldArr(res[0])
- const obj = this.formatFieldArr(res[0])
- this.fieldArr = obj.list1
- this.fieldArr2 = obj.list2
- if (res.length > 1) {
- this.detailData = res[1]
- this.batchId = this.detailData.batchId || null
- this.setDefaultForm()
- }
- this.getAuthList()
- // console.log('detailRes', res[1])
- // console.log('fieldArr', this.fieldArr)
- console.log('add ', this)
- }).catch()
- },
- /**
- * 格式化自定义字段
- */
- formatFieldArr(response) {
- let index = response.findIndex(item => ['business_cause', 'examine_cause'].includes(item.formType))
- if (index !== -1) {
- // let res = response.splice(index, 1)
- let res = response.slice(index, index + 1)
- if (res[0].formType === 'business_cause') this.causeType = 'travel'
- else if (res[0].formType === 'examine_cause') this.causeType = 'examine'
- this.causeList = []
- this.showCauseForm = true
- this.causeList.push({})
- let findRes = response.find(item => {
- return item.fieldName === 'money' || item.fieldName === 'duration'
- })
- if (findRes) {
- findRes.disabled = true
- findRes.inputTips = '根据明细自动生成'
- }
- }
- response.forEach(field => {
- field.value = this.mixinsFormatFieldValue(field)
- })
- console.log('respon', response)
- if (index !== -1) {
- return {
- list1: response.slice(0, index),
- list2: response.slice(index + 1)
- }
- } else {
- return {
- list1: response,
- list2: []
- }
- }
- },
- setDefaultForm() {
- const lib = {
- img: 'imgList',
- file: 'fileList',
- customerList: 'customerList',
- businessList: 'businessList',
- contractList: 'contractList',
- contactsList: 'contactsList'
- }
- Object.keys(lib).forEach(key => {
- this[lib[key]] = this.detailData[key] || []
- })
- this.causeList = this.detailData.examineTravelList || []
- if (this.causeList.length === 0) this.causeList.push({})
- this.$nextTick(() => {
- console.log(this.detailData)
- // this.fieldArr.forEach(field => {
- // if (field.value instanceof Array) field.value = field.value.join(',')
- // this.$refs.form.setForm(null, field.fieldName, field.value)
- // })
- })
- },
- /**
- * 获取审批流程条件
- */
- getAuthList() {
- PreviewFiledName({
- label: 0,
- examineId: this.examineId
- }).then(res => {
- const mapIns = new Map()
- this.auditConditionFields = res.filter(o => !mapIns.has(o.fieldId) && mapIns.set(o.fieldId, 1))
- console.log('PreviewFiledName: ', this.auditConditionFields)
- this.$nextTick(() => {
- const dataMap = {}
- this.auditConditionFields.forEach(o => {
- const findRes = this.fieldArr.find(f => f.fieldName === o.fieldName)
- if (findRes) {
- let value = findRes.value
- switch (findRes.formType) {
- case 'select':
- if (this.$isEmpty(value)) value = ''
- if (isArray(value)) {
- value = value[0].value
- }
- break
- case 'checkbox':
- if (this.$isEmpty(value)) value = ''
- if (isArray(value)) {
- value = value.map(o => o.value).join(',')
- }
- break
- default:
- value = this.$isEmpty(value) ? '' : value
- }
- o._val = value
- dataMap[o.fieldName] = value
- }
- })
- this.$refs.wkAuditAdd.getAuditInfo({
- label: 0,
- examineId: this.examineId,
- dataMap
- })
- })
- }).catch(() => {})
- },
- /**
- * 根据审批条件变更审批流
- */
- changeAuditFlow(field, value) {
- const findRes = this.auditConditionFields.find(o => o.fieldName === field.fieldName)
- if (!findRes) return
- if (this.timer) {
- clearTimeout(this.timer)
- this.timer = null
- }
- this.timer = setTimeout(() => {
- // number floatnumber select checkbox
- switch (field.formType) {
- case 'select':
- if (this.$isEmpty(value)) value = ''
- if (isArray(value)) {
- value = value[0].value
- }
- break
- case 'checkbox':
- if (this.$isEmpty(value)) value = ''
- if (isArray(value)) {
- value = value.map(o => o.value).join(',')
- }
- break
- }
- findRes._val = value
- const dataMap = {}
- this.auditConditionFields.forEach(o => {
- if (o.hasOwnProperty('_val')) {
- dataMap[o.fieldName] = this.$isEmpty(o._val) ? '' : o._val
- } else {
- dataMap[o.fieldName] = ''
- }
- })
- this.$nextTick(() => {
- this.$refs.wkAuditAdd.getAuditInfo({
- label: 0,
- examineId: this.examineId,
- dataMap
- })
- clearTimeout(this.timer)
- this.timer = null
- })
- }, 500)
- },
- handleValueChange(data) {
- console.log('value change: ', data)
- this.changeAuditFlow(data.field, data.value)
- },
- /**
- * 添加附件和图片
- */
- addFile(type) {
- let params = { type: type }
- if (this.batchId) {
- params.batchId = this.batchId
- }
- let fileObj = new WkFile(params)
- fileObj.choose().then(response => {
- this.batchId = response[0].batchId
- if (type === 'img') {
- this.imgList = this.imgList.concat(response)
- } else {
- this.fileList = this.fileList.concat(response)
- }
- fileObj = null
- })
- },
- /**
- * 弹出选择关联业务
- */
- getRelevancePopOptions() {
- const map = [
- { label: '客户', value: 'customer', auth: 'crm.customer.index' },
- { label: '联系人', value: 'contacts', auth: 'crm.contacts.index' },
- { label: '商机', value: 'business', auth: 'crm.business.index' },
- { label: '合同', value: 'contract', auth: 'crm.contract.index' }
- ]
- this.popOptions = map.filter(o => {
- return this.$auth(o.auth)
- })
- this.$refs.popup.open()
- },
- /**
- * 去选择关联项
- * @param {Object} opt
- */
- handleSelectOptions(opt) {
- this.$refs.popup.close()
- console.log(opt)
- const bridge = getApp().globalData.selectedValBridge
- bridge[opt.value] = {
- guid: this.guid,
- defaultVal: this[`${opt.value}List`] || []
- }
- uni.$on('selected-relevance', this.selectedRelevance)
- this.$Router.navigateTo({
- url: '/pages_common/selectList/relevance',
- query: {
- type: opt.value
- }
- })
- },
- /**
- * 选中关联项
- * @param {Object} data
- */
- selectedRelevance(data) {
- if (this.guid === data.guid) {
- console.log('add log on: ', data)
- this[`${data.type}List`] = data.data
- }
- uni.$off('selected-relevance')
- },
- /**
- * 行程添加
- */
- handleAddTravel() {
- this.causeList.push({})
- },
- handleChangeTravel(formData, index) {
- this.$set(this.causeList, index, formData)
- },
- handleDeleteTravel(index) {
- this.showCauseForm = false
- this.causeList.splice(index, 1)
- this.$nextTick(() => {
- this.showCauseForm = true
- })
- },
- /**
- * 删除附件
- */
- handleDeleteFile(index, item) {
- const fileId = item.fileId
- this.fileList.splice(index, 1)
- FileDeleteById({ id: fileId }).then().catch()
- },
- /**
- * 删除图片
- */
- handleDeleteImg(index, item) {
- const fileId = item.fileId
- this.imgList.splice(index, 1)
- FileDeleteById({ id: fileId }).then().catch()
- },
- /**
- * 公用删除
- */
- baseDelete(type, index) {
- console.log('delete: ', type, index)
- let arr = ['customer', 'contacts', 'business', 'contract', 'img', 'file']
- if (type === 'img' || type === 'file') {
- let fileId = this[`${type}List`][index].fileId
- FileDeleteById({ id: fileId }).then().catch()
- }
- if (arr.includes(type)) {
- this[`${type}List`].splice(index, 1)
- }
- },
- checkTravel() {
- for (let i = 0; i < this.causeList.length; i++) {
- const travel = this.causeList[i]
- let startTime = travel.startTime || null
- let endTime = travel.endTime || null
- if (startTime && endTime && startTime > endTime) {
- this.$toast('开始时间不能大于结束时间')
- return false
- }
- }
- return true
- },
- handleSave() {
- let params = {
- field: [],
- oaExamineTravelList: [],
- oaExamine: {
- categoryId: this.examineId
- },
- oaExamineRelation: { // 关联业务
- customerIds: this.customerList.map(o => o.customerId).join(',') || '',
- contactsIds: this.contactsList.map(o => o.contactsId).join(',') || '',
- businessIds: this.businessList.map(o => o.businessId).join(',') || '',
- contractIds: this.contractList.map(o => o.contractId).join(',') || '',
- }
- }
- if (this.batchId) params.oaExamine.batchId = this.batchId // 文件
- if (this.id) {
- params.oaExamine.categoryId = this.examineId
- params.oaExamine.examineId = this.id
- params.oaExamine.batchId = this.detailData.batchId
- }
- const promiseArr = [this.$refs.form.getForm()]
- if (this.fieldArr2.length > 0) {
- promiseArr.push(this.$refs.form2.getForm())
- }
- Promise.all(promiseArr).then(resArr => {
- const res1 = resArr[0]
- const res2 = resArr.length > 1 ? resArr[1] : { field: [], entity: {}}
- params.field = [...res1.field, ...res2.field]
- params.oaExamine = {
- ...params.oaExamine,
- ...res1.entity,
- ...res2.entity
- }
- let startTime = params.oaExamine.startTime || params.oaExamine.start_time || null
- let endTime = params.oaExamine.endTime || params.oaExamine.end_time || null
- if (startTime && endTime && startTime > endTime) {
- this.$toast('审批开始时间不能大于结束时间')
- return;
- }
- // 行程/差旅明细
- if (this.showCauseForm) {
- if (!this.checkTravel()) return;
- params.oaExamineTravelList = this.causeList.map(o => {
- const item = {...o}
- delete o.img
- return item
- })
- }
- // 审批信息
- const data = this.$refs.wkAuditAdd.getSaveData()
- if (data === null) return
- const dataMap = {}
- this.auditConditionFields.forEach(o => {
- if (o.hasOwnProperty('_val')) {
- dataMap[o.fieldName] = this.$isEmpty(o._val) ? '' : o._val
- }
- })
- params.examineFlowData = {
- ...data,
- label: 0,
- examineId: this.examineId,
- dataMap
- }
- params.field = params.field
- .filter(o => o.formType !== 'desc_text')
- .map(o => {
- return {
- fieldName: o.fieldName,
- name: o.name,
- type: o.type,
- fieldId: o.fieldId,
- value: o.value,
- fieldType: o.fieldType
- }
- })
- console.log('save: ', params)
- SetOaExamine(params).then(() => {
- this.$toast(this.id ? '修改成功' : '添加成功')
- this.$refreshAndToPrev(this)
- }).catch()
- })
- }
- }
- }
- </script>
- <style scoped lang="scss">
- .main-container {
- .container {
- flex: 1;
- // padding: 20rpx 0;
- overflow: hidden;
- .scroll-content {
- width: 100%;
- height: 100%;
- overflow: auto;
- }
- .travel-item-footer {
- width: 100%;
- height: 80rpx;
- font-size: 30rpx;
- color: $theme-color;
- background-color: #F3F5FA;
- @include center;
- .add-icon {
- font-size: 32rpx;
- color: $theme-color;
- margin-right: 15rpx;
- }
- }
- .attachment {
- margin-top: 20rpx;
- background-color: #fff;
- padding: 0 30rpx;
- color: $dark;
- font-size: 30rpx;
- .attachment-box {
- padding: 20rpx 0;
- border-bottom: 1rpx solid $border-color;
- .attachment-title {
- width: 100%;
- font-size: 30rpx;
- @include left;
- .left {
- flex: 1;
- @include left;
- .pic-icon {
- width: 38rpx;
- height: 38rpx;
- margin-right: 15rpx;
- }
- }
- .add-icon {
- width: 38rpx;
- height: 38rpx;
- background-color: #E1E1E1;
- border-radius: 50%;
- @include center;
- .wk {
- font-size: $wk-font-mini;
- line-height: normal;
- color: white;
- }
- }
- }
- .attachment-content {
- padding-top: 20rpx;
- @include left;
- .attachment-content-item {
- @include center;
- flex-direction: column;
- position: relative;
- }
- .icon {
- width: 22rpx;
- height: 22rpx;
- position: absolute;
- right: 0;
- top: 0;
- }
- .realname {
- padding-top: 15rpx;
- }
- }
- }
- }
- }
- }
- </style>
|