lion 3 days ago
parent 98dd68a37d
commit 6ab5ebf42e

@ -3,9 +3,9 @@ ENV = 'development'
# base api
VUE_APP_DOMIAN=http://192.168.60.99:9003/
VUE_APP_DOMIAN=http://192.168.60.99:8003/
VUE_APP_BASE_API = ''
VUE_APP_UPLOAD=http://192.168.60.99:9003/api/admin/upload-file
VUE_APP_UPLOAD=http://192.168.60.99:8003/api/admin/upload-file
VUE_APP_OUT_URL = http://192.168.60.18:8001
#VUE_APP_DOMIAN=http://192.168.60.99:9003/

@ -1017,8 +1017,15 @@ export default {
model: 'Contract'
}).then(res => {
this.templateContextData = res
//
this.initTemplateFields(res)
// DOMHTML
if (this.currentStep === 2) {
this.$nextTick(() => {
this.initTemplateFields(res)
})
} else {
// HTML
this.initTemplateFields(res)
}
})
}
@ -1071,11 +1078,75 @@ export default {
}
},
// HTML
fillFieldsInHtml(html, fields) {
if (!html || !fields) return html
let filledHtml = html
fields.forEach(field => {
if (field.link_field && field.value !== undefined && field.value !== null && field.value !== '') {
const fieldValue = String(field.value)
// textarea
const textareaRegex = new RegExp(`(<textarea[^>]*data-field="${field.field}"[^>]*>)([\\s\\S]*?)(</textarea>)`, 'gi')
if (textareaRegex.test(filledHtml)) {
filledHtml = filledHtml.replace(textareaRegex, (match, openTag, content, closeTag) => {
return `${openTag}${fieldValue}${closeTag}`
})
}
// input, select
const singleTagRegex = new RegExp(`<([^>]*data-field="${field.field}"[^>]*)>`, 'gi')
filledHtml = filledHtml.replace(singleTagRegex, (match) => {
const controlType = this.getControlType(match)
if (controlType === 'checkbox' || controlType === 'radio') {
// checked
const currentValue = this.getControlValue(match)
if (String(fieldValue) === String(currentValue)) {
if (!match.includes('checked')) {
return match.replace('>', ' checked>')
}
} else {
// checked
return match.replace(/\s+checked(\s|>)/g, '$1')
}
} else {
// value
if (!match.includes('value=')) {
return match.replace('>', ` value="${fieldValue}">`)
} else {
return match.replace(/value="[^"]*"/i, `value="${fieldValue}"`)
}
}
return match
})
}
})
return filledHtml
},
//
getControlType(controlHtml) {
if (controlHtml.includes('type="checkbox"')) return 'checkbox'
if (controlHtml.includes('type="radio"')) return 'radio'
if (controlHtml.includes('<select')) return 'select'
if (controlHtml.includes('<textarea')) return 'textarea'
return 'text'
},
//
getControlValue(controlHtml) {
const valueMatch = controlHtml.match(/value="([^"]*)"/)
return valueMatch ? valueMatch[1] : ''
},
//
initTemplateFieldsForTable(fields, contextData, tableIndex) {
//
//
fields.forEach(field => {
// link_typeother_data_fill
// link_fieldother_data_fill
if (field.link_field && contextData.other_data_fill[field.link_field]) {
let value = contextData.other_data_fill[field.link_field]
@ -1086,34 +1157,54 @@ export default {
//
field.value = value
}
})
// DOM
// DOM
if (this.currentStep === 2) {
this.$nextTick(() => {
const dom = tableIndex === 1 ? this.$refs.mainTable1 : this.$refs.mainTable2
if (dom) {
const input = dom.querySelector(`[data-field="${field.field}"]`)
if (input) {
if (input.type === 'checkbox' || input.type === 'radio') {
if (field.value === input.value) {
input.checked = true
// DOM
fields.forEach(field => {
if (field.link_field && field.value !== undefined && field.value !== null && field.value !== '') {
const input = dom.querySelector(`[data-field="${field.field}"]`)
if (input) {
if (input.type === 'checkbox' || input.type === 'radio') {
if (String(field.value) === input.value) {
input.checked = true
}
} else if (input.tagName.toLowerCase() === 'textarea') {
input.textContent = field.value
} else {
input.value = field.value
}
}
} else {
input.value = field.value
}
})
// tab
const updatedForms = syncFormDomToHtml(dom, fields)
if (tableIndex === 1) {
this.forms1 = updatedForms
this.forms = this.forms1 // 使
} else if (tableIndex === 2) {
this.forms2 = updatedForms
}
}
}
})
// tab
const dom = tableIndex === 1 ? this.$refs.mainTable1 : this.$refs.mainTable2
if (dom) {
const updatedForms = syncFormDomToHtml(dom, fields)
if (tableIndex === 1) {
this.forms1 = updatedForms
this.forms = this.forms1 // 使
} else if (tableIndex === 2) {
this.forms2 = updatedForms
})
} else {
// HTML
let html = tableIndex === 1 ? this.forms1 : this.forms2
if (html) {
html = this.fillFieldsInHtml(html, fields)
if (tableIndex === 1) {
this.forms1 = html
this.forms = this.forms1
} else if (tableIndex === 2) {
this.forms2 = html
}
}
}
},
@ -1307,8 +1398,13 @@ export default {
if (res) {
//
this.currentStep = 2
// amount
// amount
this.$nextTick(() => {
//
if (this.templateContextData) {
this.initTemplateFields(this.templateContextData)
}
// amount
this.setupAmountListeners(this.$refs.mainTable1)
this.setupAmountListeners(this.$refs.mainTable2)
})
@ -1323,8 +1419,13 @@ export default {
} else {
//
this.currentStep = 2
// amount
// amount
this.$nextTick(() => {
//
if (this.templateContextData) {
this.initTemplateFields(this.templateContextData)
}
// amount
this.setupAmountListeners(this.$refs.mainTable1)
this.setupAmountListeners(this.$refs.mainTable2)
})

File diff suppressed because it is too large Load Diff

@ -284,21 +284,39 @@
</Button>
</template>
<!-- (scope.row.purchase_way ? scope.row.purchase_way.remark === 'true' : false) && -->
<template
v-if="scope.row.invite_status === 1 && scope.row.purchase_status === 3 && !scope.row.is_substitute && (!scope.row.contract_category || scope.row.invite_status === 1)"
>
<Button class="slot-btns-item" size="small" type="primary" @click="bidding(scope.row)"></Button>
<!-- 旧合同的招标审查 -->
<!-- contract_category.flow_invite -->
<!-- 新合同的招标审查 =1 且如果需要走采购采购=3 -->
<template v-if="scope.row.contract_category">
<!-- 如果需要 走采购 且采购状态=3 需要走招标flow_invite=1就可以走招标审查 -->
<!-- 如果不需要走采购 只需要走招标的flow_invite=1就可以走招标审查 -->
<!-- invite_status=3 代表招标审查已结束不需要显示按钮 -->
<template v-if="scope.row.contract_category.flow_purchase && scope.row.purchase_status === 3 && scope.row.contract_category.flow_invite==1 && scope.row.invite_status == 1">
<Button class="slot-btns-item" size="small" type="primary" @click="bidding(scope.row)"></Button>
</template>
<template v-else-if="!scope.row.contract_category.flow_purchase && scope.row.contract_category.flow_invite==1 && scope.row.invite_status == 1">
<Button class="slot-btns-item" size="small" type="primary" @click="bidding(scope.row)"></Button>
</template>
</template>
<template v-else>
<template
v-if="scope.row.invite_status === 1 && scope.row.purchase_status === 3 && (scope.row.purchase_way ? scope.row.purchase_way.remark === 'true' : false) && !scope.row.is_substitute"
>
<Button class="slot-btns-item" size="small" type="primary" @click="bidding(scope.row)"></Button>
</template>
</template>
<!-- <Button class="slot-btns-item" type="primary" size="small">附件管理</Button>-->
<template v-if="scope.row.req_status === 1 && (scope.row.is_plan === 0 && !scope.row.is_substitute || scope.row.has_charge) && (!scope.row.contract_category || scope.row.req_status === 1)">
<Button class="slot-btns-item" size="small" type="primary" @click="askProcess(scope.row)">
</Button>
</template>
<!--不需要走采购流程那么直接就是会签如果采购方式不需要招标的也是直接会签-->
<!-- (scope.row.purchase_way ? scope.row.purchase_way.remark === 'false' : false) -->
<template
v-if="(scope.row.has_charge && scope.row.req_status === 3 && scope.row.join_status === 1) || (scope.row.join_status === 1 && ((scope.row.invite_status === 3)||(scope.row.purchase_status === 3)) || ( scope.row.is_substitute && scope.row.join_status === 1) ) && (!scope.row.contract_category || scope.row.join_status === 1)"
v-if="(scope.row.has_charge && scope.row.req_status === 3 && scope.row.join_status === 1) || (scope.row.join_status === 1 && ((scope.row.invite_status === 3)||(scope.row.purchase_status === 3 && (!scope.row.contract_category || !scope.row.contract_category.flow_invite || scope.row.invite_status === 3))) || ( scope.row.is_substitute && scope.row.join_status === 1) ) && (!scope.row.contract_category || scope.row.join_status === 1)"
>
<Button class="slot-btns-item" size="small" type="primary" @click="signProcess(scope.row)">
</Button>
@ -309,18 +327,19 @@
<Button class="slot-btns-item" size="small" type="primary" @click="buyProcess(scope.row)">
</Button>
</template>
<!-- v-if="!(scope.row.req_status != 1 || scope.row.join_status != 1 || scope.row.invite_status != 1 || scope.row.purchase_status != 1 || scope.row.status === 2)" -->
<Poptip trigger="hover" placement="bottom" transfer>
<Button ghost size="small" type="primary">更多</Button>
<div slot="content">
<template
v-if="!(scope.row.req_status != 1 || scope.row.join_status != 1 || scope.row.invite_status != 1 || scope.row.purchase_status != 1 || scope.row.status === 2)"
>
v-if="$store.state.user.myRole.find(i => /财审科|系统管理员/g.test(i.name))"
>
<Poptip
:transfer="true"
confirm
placement="bottom"
title="确认要删除吗"
title="可能存在已办结的流程,确认要删除吗"
@on-ok="()=>deleteContract(scope.row.id)"
>
<i-button class="slot-btns-item" ghost size="small" type="error">删除
@ -866,6 +885,37 @@
<printRegistration ref="printRegistration" />
<printFundApproval ref="printFundApproval" />
<printPaymentForm ref="printPaymentForm" />
<!-- OA流程流水号弹窗 -->
<Modal
v-model="isShowFlowDialog"
title="填写OA流程流水号"
@on-ok="submitFlowId"
@on-cancel="cancelFlowDialog"
>
<div style="padding: 20px 0;">
<div style="margin-bottom: 15px;">
<span style="display: inline-block; width: 100px; text-align: right; margin-right: 10px;">流水号</span>
<Input
v-model="flowId"
placeholder="请输入OA流程流水号"
style="width: 300px;"
@on-enter="submitFlowId"
/>
</div>
<div style="margin-bottom: 15px;">
<span style="display: inline-block; width: 100px; text-align: right; margin-right: 10px;">状态</span>
<Select
v-model="flowStatus"
style="width: 300px;"
placeholder="请选择状态"
>
<Option :value="0">流转中</Option>
<Option :value="1">已办结</Option>
</Select>
</div>
</div>
</Modal>
</div>
</template>
@ -876,7 +926,8 @@ import {
delContract,
checkContractName,
editorContract,
detailContract
detailContract,
updateContract
} from '@/api/contract/contract'
import {
getparameter
@ -1196,118 +1247,188 @@ export default {
},
{
label: '采购流程',
multiHd: [{
multiHd: [ {
label: '请示流程',
width: 140,
prop: 'req_status',
formatter: (cell, data, value) => {
if (cell.is_substitute && !cell.has_charge) {
return '无'
}
if (cell.is_plan === 1 && !cell.has_charge) {
return '无'
}
switch (value) {
case 0:
return '无'
break
case 1:
return '待申请'
break
case 2:
return '流转中'
break
case 3:
return '已办结'
break
default:
return '异常'
break
customFn: (row) => {
let statusText = '无'
if (!(row.is_substitute && !row.has_charge) && !(row.is_plan === 1 && !row.has_charge)) {
switch (row.req_status) {
case 0:
statusText = '无'
break
case 1:
statusText = '待申请'
break
case 2:
statusText = '流转中'
break
case 3:
statusText = '已办结'
break
default:
statusText = '异常'
break
}
}
const needFlow = !(row.is_substitute && !row.has_charge) && !(row.is_plan === 1 && !row.has_charge)
const canEdit = needFlow && row.req_status > 0 && row.req_status <= 3 &&
this.$store.state.user.myRole &&
this.$store.state.user.myRole.find(i => /财审科|系统管理员/g.test(i.name))
return (
<div style="display: flex; align-items: center; justify-content: space-between;">
<span>{statusText}</span>
{canEdit && (
<i
class="el-icon-edit"
style="cursor: pointer; color: #409EFF; margin-left: 5px;"
on-click={(e) => {
e.stopPropagation()
this.openFlowDialog(row, 'qingshi')
}}
/>
)}
</div>
)
}
},
{
label: '采购业务审批流程',
width: 158,
prop: 'purchase_status',
formatter: (cell, data, value) => {
if (cell.is_substitute || cell.is_simple) {
return '无'
}
switch (value) {
case 0:
return '无'
break
case 1:
return '待申请'
break
case 2:
return '流转中'
break
case 3:
return '已办结'
break
default:
return '异常'
break
customFn: (row) => {
let statusText = '无'
if (!row.is_substitute && !row.is_simple) {
switch (row.purchase_status) {
case 0:
statusText = '无'
break
case 1:
statusText = '待申请'
break
case 2:
statusText = '流转中'
break
case 3:
statusText = '已办结'
break
default:
statusText = '异常'
break
}
}
const needFlow = !row.is_substitute && !row.is_simple
const canEdit = needFlow && row.purchase_status > 0 && row.purchase_status <= 3 &&
this.$store.state.user.myRole &&
this.$store.state.user.myRole.find(i => /财审科|系统管理员/g.test(i.name))
return (
<div style="display: flex; align-items: center; justify-content: space-between;">
<span>{statusText}</span>
{canEdit && (
<i
class="el-icon-edit"
style="cursor: pointer; color: #409EFF; margin-left: 5px;"
on-click={(e) => {
e.stopPropagation()
this.openFlowDialog(row, 'caigou')
}}
/>
)}
</div>
)
}
},
{
label: '招标审核流程',
width: 145,
prop: 'invite_status',
formatter: (cell, data, value) => {
if (cell.is_substitute || cell.is_simple) {
return '无'
}
if (cell.purchase_way?.remark === 'false') {
return '无'
}
switch (value) {
case 0:
return '无'
break
case 1:
return '待申请'
break
case 2:
return '流转中'
break
case 3:
return '已办结'
break
default:
return '异常'
break
customFn: (row) => {
let statusText = '无'
if (!row.is_substitute && !row.is_simple && row.purchase_way?.remark !== 'false') {
switch (row.invite_status) {
case 0:
statusText = '无'
break
case 1:
statusText = '待申请'
break
case 2:
statusText = '流转中'
break
case 3:
statusText = '已办结'
break
default:
statusText = '异常'
break
}
}
const needFlow = !row.is_substitute && !row.is_simple && row.purchase_way?.remark !== 'false'
const canEdit = needFlow && row.invite_status > 0 && row.invite_status <= 3 &&
this.$store.state.user.myRole &&
this.$store.state.user.myRole.find(i => /财审科|系统管理员/g.test(i.name))
return (
<div style="display: flex; align-items: center; justify-content: space-between;">
<span>{statusText}</span>
{canEdit && (
<i
class="el-icon-edit"
style="cursor: pointer; color: #409EFF; margin-left: 5px;"
on-click={(e) => {
e.stopPropagation()
this.openFlowDialog(row, 'zhaobiaowenjianshencha')
}}
/>
)}
</div>
)
}
},
{
label: '合同会签流程',
width: 145,
prop: 'join_status',
formatter: (cell, data, value) => {
if (cell.is_simple) {
return '无'
}
switch (value) {
case 0:
return '无'
break
case 1:
return '待申请'
break
case 2:
return '流转中'
break
case 3:
return '已办结'
break
default:
return '异常'
break
customFn: (row) => {
let statusText = '无'
if (!row.is_simple) {
switch (row.join_status) {
case 0:
statusText = '无'
break
case 1:
statusText = '待申请'
break
case 2:
statusText = '流转中'
break
case 3:
statusText = '已办结'
break
default:
statusText = '异常'
break
}
}
const needFlow = !row.is_simple
const canEdit = needFlow && row.join_status > 0 && row.join_status <= 3 &&
this.$store.state.user.myRole &&
this.$store.state.user.myRole.find(i => /财审科|系统管理员/g.test(i.name))
return (
<div style="display: flex; align-items: center; justify-content: space-between;">
<span>{statusText}</span>
{canEdit && (
<i
class="el-icon-edit"
style="cursor: pointer; color: #409EFF; margin-left: 5px;"
on-click={(e) => {
e.stopPropagation()
this.openFlowDialog(row, 'hetonghuiqian')
}}
/>
)}
</div>
)
}
}
]
@ -1652,6 +1773,13 @@ export default {
availableYears: [],
planTotal: 0,
plansPageIndex: 1,
// OA
isShowFlowDialog: false,
currentFlow: '', // : qingshi, caigou, zhaobiaowenjianshencha, hetonghuiqian
currentRow: null, //
flowId: '', //
flowStatus: 0, // : 0, 1
oatoken: '', // OA token
isShowEditor: false,
contractTypes: [
@ -2470,22 +2598,34 @@ export default {
//
this.isShowAdd = false
//
const res = await getContract({
page_size: 1,
page: 1,
is_auth: 1
})
//
let contractData = null
if (this.isEditMode && this.currentContractId) {
//
const res = await getContract({ id: this.currentContractId })
if (res && res.list && res.list.data && res.list.data.length > 0) {
contractData = res.list.data[0]
}
} else {
//
const res = await getContract({
page_size: 1,
page: 1,
is_auth: 1
})
if (res.list.data && res.list.data.length > 0) {
contractData = res.list.data[0]
}
}
//
if (res.list.data && res.list.data.length > 0) {
const firstContract = res.list.data[0]
if (firstContract.req_status === 0 &&
firstContract.purchase_status === 0 &&
firstContract.invite_status === 0 &&
firstContract.join_status === 0) {
//
if (contractData) {
if (contractData.req_status === 0 &&
contractData.purchase_status === 0 &&
contractData.invite_status === 0 &&
contractData.join_status === 0) {
// 0
this.$refs['paymentRegistration'].getContract(firstContract)
this.$refs['paymentRegistration'].getContract(contractData)
this.$refs['paymentRegistration'].isShowPaymentRegistration = true
}
}
@ -2518,6 +2658,86 @@ export default {
this.getContracts()
})
},
// OA
openFlowDialog(row, flowType) {
const flow2contractField = new Map([
['caigou', 'purchase_status'],
['hetonghuiqian', 'join_status'],
['qingshi', 'req_status'],
['zhaobiaowenjianshencha', 'invite_status']
])
this.currentRow = row
this.currentFlow = flowType
this.flowId = ''
// OA
// 0 1
// 1 2-> 03-> 1
const currentStatus = row[flow2contractField.get(flowType)]
if (currentStatus === 3) {
this.flowStatus = 1 //
} else {
this.flowStatus = 0 //
}
this.isShowFlowDialog = true
},
//
cancelFlowDialog() {
this.isShowFlowDialog = false
this.currentRow = null
this.currentFlow = ''
this.flowId = ''
this.flowStatus = 0
},
// OA
async submitFlowId() {
if (!this.flowId || !this.flowId.trim()) {
Message({
type: 'warning',
message: '请输入OA流程流水号'
})
return
}
try {
const flow_type = new Map([
['caigou', 2],
['hetonghuiqian', 3],
['qingshi', 17],
['zhaobiaowenjianshencha', 27]
])
const flow2contractField = new Map([
['caigou', 'purchase_status'],
['hetonghuiqian', 'join_status'],
['qingshi', 'req_status'],
['zhaobiaowenjianshencha', 'invite_status']
])
if (!this.oatoken) {
const res = await getOatoken()
this.oatoken = res.oatoken
}
await updateContract({
out_contract_id: this.currentRow.id,
flow_type: flow_type.get(this.currentFlow),
status: this.flowStatus,
flow_id: this.flowId.trim()
})
Message({
type: 'success',
message: '提交成功'
})
this.cancelFlowDialog()
this.getContracts()
} catch (error) {
console.error('提交失败:', error)
Message({
type: 'error',
message: '提交失败,请重试'
})
}
},
handleCategoryChange() {
this.form.affairType = ''
this.form.contractType = ''

@ -184,6 +184,19 @@ export default {
)
}
},
{
prop: 'remaining_money',
label: '剩余金额',
align: 'right',
width: 180,
formatter: (cell, data, value) => {
const updateMoney = Number(cell.update_money || 0)
const money = Number(cell.money || 0)
const useMoney = Number(cell.use_money_total || 0)
const remaining = (updateMoney || money) - useMoney
return moneyFormatter(remaining)
}
},
{
prop: 'calculation_result',
label: '进展率',
@ -289,6 +302,11 @@ export default {
sums[index] = moneyFormatter(this.useMoneyTotal)
}
if (column.property === 'remaining_money') {
const remainingTotal = (this.updateMoneyTotal || this.moneyTotal) - this.useMoneyTotal
sums[index] = moneyFormatter(remainingTotal)
}
if (column.property === 'money') {
sums[index] = moneyFormatter(this.moneyTotal)
}

@ -179,11 +179,18 @@ export default {
return arr
})(),
{
label: '合计',
label: '计划支出合计',
width: 120,
prop: 'total',
align: 'right',
formatter: (v1, v2, val) => (val.toFixed(2))
},
{
label: '实际支出合计',
width: 120,
prop: 'actTotal',
align: 'right',
formatter: (v1, v2, val) => (val.toFixed(2))
}
]
}
@ -406,6 +413,7 @@ export default {
arr.push(i.impltRate[z])
}
arr.push(i.total)
arr.push(i.actTotal)
return arr
})
const header = [[], []]
@ -459,6 +467,16 @@ export default {
start += index
}
ws['!merges'].push(
{
s: {
c: xlsxData[0].length - 2,
r: 0
},
e: {
c: xlsxData[0].length - 2,
r: 1
}
},
{
s: {
c: xlsxData[0].length - 1,
@ -532,7 +550,8 @@ export default {
impltRate: planExpend.map((j, ji) => (this.percent(parseFloat(actExpend[ji]), parseFloat(j)))),
total: plan.detail?.reduce((a, b) => {
return a + parseFloat(b.plan_total ?? 0)
}, 0)
}, 0),
actTotal: actExpend.reduce((pre, cur) => (pre + parseFloat(cur)), 0)
})
})
//
@ -570,6 +589,7 @@ export default {
actExpend,
impltRate: planExpend.map((j, ji) => (this.percent(parseFloat(actExpend[ji]), parseFloat(j)))),
total: planExpend.reduce((pre, cur) => (pre + parseFloat(cur)), 0),
actTotal: actExpend.reduce((pre, cur) => (pre + parseFloat(cur)), 0),
children
})
}

Loading…
Cancel
Save