|
|
@@ -1,153 +1,236 @@
|
|
|
<template>
|
|
|
- <!-- 中标登记弹窗编排层:Dialog 壳 + 提交逻辑;字段区见 AddContentForm -->
|
|
|
- <div class="bid-content-page">
|
|
|
- <div class="bid-container">
|
|
|
- <el-dialog v-model="dialogFormVisible" draggable title="提示信息" width="500" @close="close">
|
|
|
- <AddContentForm
|
|
|
- ref="formCompRef"
|
|
|
- :add-form="addForm"
|
|
|
- :rules="rules"
|
|
|
- :type-options="typeOptions"
|
|
|
- :jk-list="jkList"
|
|
|
- :txb-list="txbList"
|
|
|
- :yt-list="ytList"
|
|
|
- :zgfw-options="zgfwOptions"
|
|
|
- :gl-area="props.glArea"
|
|
|
- :area-project="props.areaProject"
|
|
|
- :finish-bid-object-temp="finishBidObjectTemp"
|
|
|
- v-model:admin-cascader="adminCascader"
|
|
|
- v-model:add-form-area="addFormArea"
|
|
|
- v-model:add-form-zgfw="addFormZgfw"
|
|
|
- v-model:add-form-fwlx="addFormFwlx"
|
|
|
- v-model:add-form-yt="addFormYT"
|
|
|
- @type-change="handleTypeChange"
|
|
|
- @project-change="handleProjectChange"
|
|
|
- @admin-cascader-change="handleAdminCascaderChange"
|
|
|
- @xb-switch-change="handleXBSwitchChange"
|
|
|
- @area-change="handleNodeAreaClick"
|
|
|
- />
|
|
|
- <template #footer>
|
|
|
- <div class="dialog-footer">
|
|
|
- <el-button @click="close" class="btn">取消</el-button>
|
|
|
- <el-button type="primary" class="btn enter-btn" @click="submitForm">
|
|
|
- 确认
|
|
|
- </el-button>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-dialog>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <!-- 中标登记:必建 SOURCE + 必传标书;进行中投续标写 c_terminated -->
|
|
|
+ <el-dialog
|
|
|
+ :model-value="flag"
|
|
|
+ draggable
|
|
|
+ title="中标登记"
|
|
|
+ width="640"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ @close="close"
|
|
|
+ >
|
|
|
+ <AddContentForm
|
|
|
+ ref="formCompRef"
|
|
|
+ :add-form="addForm"
|
|
|
+ :rules="rules"
|
|
|
+ :type-options="typeOptions"
|
|
|
+ :txb-list="txbList"
|
|
|
+ :yt-list="ytList"
|
|
|
+ :zgfw-options="zgfwOptions"
|
|
|
+ :jffs-options="jffsOptions"
|
|
|
+ :fkms-options="fkmsOptions"
|
|
|
+ :gl-area="props.glArea"
|
|
|
+ :area-project="props.areaProject"
|
|
|
+ :tender-uploading="tenderUploading"
|
|
|
+ :tender-file-path="tenderFilePath"
|
|
|
+ v-model:parent-cascader="parentCascader"
|
|
|
+ v-model:add-form-area="addFormArea"
|
|
|
+ v-model:add-form-zgfw="addFormZgfw"
|
|
|
+ v-model:add-form-jffs="addFormJffs"
|
|
|
+ v-model:add-form-fkms="addFormFkms"
|
|
|
+ v-model:add-form-yt="addFormYT"
|
|
|
+ @type-change="handleTypeChange"
|
|
|
+ @txb-change="handleTxbChange"
|
|
|
+ @parent-cascader-change="handleParentCascaderChange"
|
|
|
+ @xb-switch-change="handleXBSwitchChange"
|
|
|
+ @area-change="handleNodeAreaClick"
|
|
|
+ @tender-file-change="handleTenderFileChange"
|
|
|
+ />
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button class="btn" @click="close">取消</el-button>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ class="btn enter-btn"
|
|
|
+ :loading="submitting"
|
|
|
+ @click="submitForm"
|
|
|
+ >
|
|
|
+ 确认登记
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, onMounted } from 'vue'
|
|
|
+import { ref, onMounted, reactive, nextTick } from 'vue'
|
|
|
import moment from 'moment'
|
|
|
+import { ElMessage, ElLoading } from 'element-plus'
|
|
|
import api from '@/api/common'
|
|
|
-import CONFIG from '@/utils/config'
|
|
|
import { COLUMN, MODEL } from '@/constants/dmsColumns'
|
|
|
import { buildProjectTree } from '@/utils/tree'
|
|
|
-import { getDisplayUserName } from '@/utils/displayUser'
|
|
|
+import { nextSourceGuidFromLatest } from '@/utils/projectGuid'
|
|
|
+import { uploadAndVerifyFile } from '@/utils/uploadAndVerify'
|
|
|
import type { FormRules } from 'element-plus'
|
|
|
import AddContentForm from '@/components/bidResult/addContent/AddContentForm.vue'
|
|
|
|
|
|
const formCompRef = ref<InstanceType<typeof AddContentForm>>()
|
|
|
|
|
|
-const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
|
|
|
-const userName = getDisplayUserName(userInfo)
|
|
|
-
|
|
|
const props = defineProps({
|
|
|
- flag: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- close: {
|
|
|
- type: Function,
|
|
|
- default: () => {},
|
|
|
- },
|
|
|
- glArea: {
|
|
|
- type: Array,
|
|
|
- default: () => [],
|
|
|
- },
|
|
|
- areaProject: {
|
|
|
- type: Array,
|
|
|
- default: () => [],
|
|
|
- },
|
|
|
+ flag: { type: Boolean, default: false },
|
|
|
+ close: { type: Function, default: () => {} },
|
|
|
+ glArea: { type: Array, default: () => [] },
|
|
|
+ areaProject: { type: Array, default: () => [] },
|
|
|
})
|
|
|
|
|
|
-interface resultForm {
|
|
|
- [key: string]: any
|
|
|
-}
|
|
|
-const finishObject = ref<resultForm>({})
|
|
|
const finishProjects = ref<any[]>([])
|
|
|
const finishTreeProjects = ref<any[]>([])
|
|
|
+const selectedTxb = ref<any>(null)
|
|
|
+const parentProject = ref<any>(null)
|
|
|
+const tenderFileRaw = ref<File | null>(null)
|
|
|
+/** 选文件后上传+校验通过得到的路径;确认登记时写入 c_history_tender */
|
|
|
+const tenderFilePath = ref('')
|
|
|
+const tenderUploading = ref(false)
|
|
|
+const submitting = ref(false)
|
|
|
|
|
|
const txbList = ref<any[]>([])
|
|
|
-const jkList = ref<any[]>([])
|
|
|
+const ytList = ref<any[]>([])
|
|
|
+const zgfwOptions = ref<any[]>([])
|
|
|
+const jffsOptions = ref<any[]>([])
|
|
|
+const fkmsOptions = ref<any[]>([])
|
|
|
+
|
|
|
+const addFormZgfw = ref<string | number>('')
|
|
|
+const addFormJffs = ref<string | number>('')
|
|
|
+const addFormFkms = ref<string | number>('')
|
|
|
+const addFormYT = ref('')
|
|
|
+const addFormArea = ref<any[]>([])
|
|
|
+const parentCascader = ref<any[]>([])
|
|
|
+const areaCodes = ref<string[]>([])
|
|
|
+
|
|
|
+const typeOptions = ref([
|
|
|
+ { value: '新项目登记', label: '新项目登记' },
|
|
|
+ { value: '进行中投续标', label: '进行中投续标' },
|
|
|
+])
|
|
|
|
|
|
-const ytList = ref<resultForm[]>([])
|
|
|
+const emptySourceForm = () => ({
|
|
|
+ type: '新项目登记',
|
|
|
+ txbId: '' as string | number,
|
|
|
+ c_is_xb: false,
|
|
|
+ c_xmmc: '',
|
|
|
+ c_xmdz: '',
|
|
|
+ c_htqyjf: '',
|
|
|
+ c_glqynbkj: '',
|
|
|
+ c_sq: '',
|
|
|
+ c_sfzxs: '上海市',
|
|
|
+ c_htmj: null as number | null,
|
|
|
+ c_htbh: '',
|
|
|
+ c_zgxmhtksrq: '',
|
|
|
+ c_zgxmhtdqrq: '',
|
|
|
+ c_htzj: null as number | null,
|
|
|
+ c_bndhtys: null as number | null,
|
|
|
+ c_hzyt: '',
|
|
|
+ c_wtfs: '' as string | number,
|
|
|
+ c_jffs: '' as string | number,
|
|
|
+ c_fkms: '' as string | number,
|
|
|
+ c_hts: '1',
|
|
|
+ c_xms: '1',
|
|
|
+ c_xmkssj: '',
|
|
|
+ c_xmdqsj: '',
|
|
|
+ c_bcxyzj: '',
|
|
|
+ c_zbdfqk: '',
|
|
|
+ c_xmzbggrq: '',
|
|
|
+ c_xmzbgsrq: '',
|
|
|
+ c_xmtbrq: '',
|
|
|
+ c_xmzbrq: '',
|
|
|
+ tenderFile: null as any,
|
|
|
+})
|
|
|
|
|
|
-const addFormZgfw = ref('')
|
|
|
-const addFormFwlx = ref([])
|
|
|
-const addFormYT = ref('')
|
|
|
-const addFormArea = ref([])
|
|
|
-const zgfwOptions = ref<any>([])
|
|
|
-
|
|
|
-const areaObject = ref({})
|
|
|
-const adminCascader = ref([])
|
|
|
-const jkBidObject = ref<any>(null)
|
|
|
-const txbBidObject = ref<any>(null)
|
|
|
-const finishBidObject = ref<any>(null)
|
|
|
-const finishBidObjectTemp = ref({
|
|
|
- flag: false,
|
|
|
- url: '',
|
|
|
+const addForm = ref(emptySourceForm())
|
|
|
+
|
|
|
+// 规则对象保持稳定,避免切换「登记类型」时整表重算 rules 触发误提示
|
|
|
+const rules = reactive<FormRules>({
|
|
|
+ type: [{ required: true, message: '请选择登记类型', trigger: 'change' }],
|
|
|
+ txbId: [
|
|
|
+ {
|
|
|
+ validator: (_r, v, cb) => {
|
|
|
+ if (addForm.value.type === '进行中投续标' && (v === '' || v == null)) {
|
|
|
+ cb(new Error('请选择进行中投续标'))
|
|
|
+ } else cb()
|
|
|
+ },
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ c_xmmc: [{ required: true, message: '请输入项目名称', trigger: 'blur' }],
|
|
|
+ c_xmdz: [{ required: true, message: '请输入项目地址', trigger: 'blur' }],
|
|
|
+ c_htqyjf: [{ required: true, message: '请输入合同签约甲方', trigger: 'blur' }],
|
|
|
+ c_glqynbkj: [{ required: true, message: '请选择管理区域', trigger: 'change' }],
|
|
|
+ c_zgxmhtksrq: [{ required: true, message: '请选择合同开始日期', trigger: 'change' }],
|
|
|
+ c_zgxmhtdqrq: [{ required: true, message: '请选择合同到期日期', trigger: 'change' }],
|
|
|
+ c_hzyt: [{ required: true, message: '请选择业态', trigger: 'change' }],
|
|
|
+ tenderFile: [
|
|
|
+ {
|
|
|
+ validator: (_r, _v, cb) => {
|
|
|
+ if (!tenderFilePath.value) cb(new Error('请上传并通过校验的项目标书(.docx / .pdf)'))
|
|
|
+ else cb()
|
|
|
+ },
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
})
|
|
|
|
|
|
onMounted(() => {
|
|
|
initData()
|
|
|
- getDmsTypes()
|
|
|
+ loadDicts()
|
|
|
})
|
|
|
|
|
|
-const getDmsTypes = () => {
|
|
|
- let params = {
|
|
|
- type: 0,
|
|
|
- cName: 'sq_wtfs',
|
|
|
+const close = () => {
|
|
|
+ props.close()
|
|
|
+}
|
|
|
+
|
|
|
+const loadDicts = async () => {
|
|
|
+ const [wt, jf, fk] = await Promise.all([
|
|
|
+ getDmsTypes('sq_wtfs'),
|
|
|
+ getDmsTypes('sq_jffs'),
|
|
|
+ getSelectOptions('shenqin_fkms'),
|
|
|
+ ])
|
|
|
+ zgfwOptions.value = wt
|
|
|
+ jffsOptions.value = jf
|
|
|
+ fkmsOptions.value = fk
|
|
|
+}
|
|
|
+
|
|
|
+const getDmsTypes = async (cName: string) => {
|
|
|
+ const res = await api.getDmsTypes({ type: 0, cName } as any)
|
|
|
+ if ((res as any).code === 200) {
|
|
|
+ // value 统一成字符串,避免首项 index=0 与空串 '' 发生 == 误判导致无法点选
|
|
|
+ return ((res as any).content || []).map((item: any) => ({
|
|
|
+ ...item,
|
|
|
+ label: item.name,
|
|
|
+ value: String(item.index),
|
|
|
+ }))
|
|
|
}
|
|
|
- api.getDmsTypes(params).then((res) => {
|
|
|
- if ((res as any).code === 200) {
|
|
|
- let ret = (res as any).content
|
|
|
- zgfwOptions.value = ret.map((item: any) => ({
|
|
|
- ...item,
|
|
|
- label: item.name,
|
|
|
- value: item.index,
|
|
|
- }))
|
|
|
- } else {
|
|
|
- zgfwOptions.value = []
|
|
|
- }
|
|
|
- })
|
|
|
+ return []
|
|
|
+}
|
|
|
+
|
|
|
+const getSelectOptions = async (sName: string) => {
|
|
|
+ const res = await api.getSelectBySName({ sName })
|
|
|
+ if ((res as any).code === 200 && Array.isArray((res as any).content)) {
|
|
|
+ return (res as any).content.map((item: any) => ({
|
|
|
+ ...item,
|
|
|
+ label: item.name,
|
|
|
+ value: String(item.index),
|
|
|
+ }))
|
|
|
+ }
|
|
|
+ return []
|
|
|
}
|
|
|
|
|
|
const initData = async () => {
|
|
|
await getFinishProjects()
|
|
|
- const itemTxbList = await getTypeProjects(COLUMN.TXB) // 投续标项目
|
|
|
- const itemJkList = await getTypeProjects(COLUMN.KB_MONITOR) // 中标监控项目
|
|
|
- const itemYtList = await getTypeProjects(COLUMN.SERVICE_TYPE) // 业态
|
|
|
+ const [itemTxbList, itemYtList] = await Promise.all([
|
|
|
+ getTypeProjects(COLUMN.TXB),
|
|
|
+ getTypeProjects(COLUMN.SERVICE_TYPE),
|
|
|
+ ])
|
|
|
txbList.value = []
|
|
|
- jkList.value = []
|
|
|
- ytList.value = []
|
|
|
- itemTxbList.data.filter((item: any) => {
|
|
|
- const json = JSON.parse(item.c_xmjd_json)
|
|
|
- if (json.length > 0 && json[json.length - 1].xmjd < 6) {
|
|
|
- txbList.value.push(item)
|
|
|
- }
|
|
|
- })
|
|
|
- itemJkList.data.filter((item: any) => {
|
|
|
- const flag = item.c_sfzb
|
|
|
- if (flag == false) {
|
|
|
- // 已中标
|
|
|
- jkList.value.push(item)
|
|
|
+ ;(itemTxbList?.data || []).forEach((item: any) => {
|
|
|
+ if (item.c_terminated === true || item.c_terminated === 'true') return
|
|
|
+ try {
|
|
|
+ const json = JSON.parse(item.c_xmjd_json || '[]')
|
|
|
+ if (json.length > 0 && json[json.length - 1].xmjd < 6) {
|
|
|
+ txbList.value.push(item)
|
|
|
+ }
|
|
|
+ } catch {
|
|
|
+ /* ignore */
|
|
|
}
|
|
|
})
|
|
|
- ytList.value = itemYtList.data.map((item: any) => ({
|
|
|
+ ytList.value = (itemYtList?.data || []).map((item: any) => ({
|
|
|
...item,
|
|
|
label: item.c_yt_name,
|
|
|
value: item.c_yt_name,
|
|
|
@@ -155,458 +238,475 @@ const initData = async () => {
|
|
|
}))
|
|
|
}
|
|
|
|
|
|
-const dialogFormVisible = props.flag
|
|
|
-const close = () => {
|
|
|
- props.close()
|
|
|
-}
|
|
|
-
|
|
|
const getFinishProjects = async () => {
|
|
|
const params: any = {
|
|
|
- columnId: COLUMN.SOURCE, // 原项目数据
|
|
|
+ columnId: COLUMN.SOURCE,
|
|
|
orderBy: JSON.stringify([{ field: 'c_zgxmhtdqrq', orderByType: 1 }]),
|
|
|
- states: '0', // 只看草稿箱
|
|
|
+ states: '0,1,2,3',
|
|
|
pageSize: 9999,
|
|
|
page: 0,
|
|
|
}
|
|
|
- await api.getDmsDataList(params).then((res) => {
|
|
|
- if ((res as any).code === 200) {
|
|
|
- finishProjects.value = (res as any).content.data
|
|
|
- finishTreeProjects.value = buildProjectTree(finishProjects.value)
|
|
|
- } else {
|
|
|
- finishProjects.value = []
|
|
|
- }
|
|
|
- })
|
|
|
+ const res = await api.getDmsDataList(params)
|
|
|
+ if ((res as any).code === 200) {
|
|
|
+ finishProjects.value = (res as any).content.data || []
|
|
|
+ finishTreeProjects.value = buildProjectTree(finishProjects.value)
|
|
|
+ } else {
|
|
|
+ finishProjects.value = []
|
|
|
+ finishTreeProjects.value = []
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-const typeOptions = ref([
|
|
|
- {
|
|
|
- value: '新登记',
|
|
|
- label: '新登记',
|
|
|
- },
|
|
|
- {
|
|
|
- value: '监控中未中标',
|
|
|
- label: '监控中未中标',
|
|
|
- },
|
|
|
- {
|
|
|
- value: '投续标中登记',
|
|
|
- label: '投续标中登记',
|
|
|
- },
|
|
|
-])
|
|
|
-
|
|
|
-const addForm = ref({
|
|
|
- id: '',
|
|
|
- type: '新登记',
|
|
|
- title: '',
|
|
|
- tb_date: '',
|
|
|
- tb_money: '',
|
|
|
- zb_code: '',
|
|
|
- zb_name: '',
|
|
|
- zb_org: '',
|
|
|
- zb_source: '',
|
|
|
- zb_money: '',
|
|
|
- zb_startdate: '',
|
|
|
- zb_enddate: '',
|
|
|
- zb_url: '',
|
|
|
- c_is_xb: false,
|
|
|
-})
|
|
|
-
|
|
|
-const rules = ref<FormRules>({})
|
|
|
+const getTypeProjects = async (columnId: number) => {
|
|
|
+ const params: any = {
|
|
|
+ columnId,
|
|
|
+ orderBy: JSON.stringify([{ field: 'update_time', orderByType: 2 }]),
|
|
|
+ states: '0,1,2,3',
|
|
|
+ pageSize: 9999,
|
|
|
+ page: 0,
|
|
|
+ }
|
|
|
+ const res = await api.getDmsDataList(params)
|
|
|
+ return (res as any).content
|
|
|
+}
|
|
|
|
|
|
-const submitForm = () => {
|
|
|
- const formEl = formCompRef.value?.formRef
|
|
|
- if (!formEl) return
|
|
|
- formEl.validate(async (valid) => {
|
|
|
- if (valid) {
|
|
|
- if (addForm.value.type == '监控中未中标') {
|
|
|
- // 流程
|
|
|
- const id = 7 // 固定进度数值
|
|
|
- const rwlcqd = JSON.parse(txbBidObject.value.rwlcqd || '[]')
|
|
|
- rwlcqd.find((p: any) => p.id == id).done = true
|
|
|
- rwlcqd.find((p: any) => p.id == id).create_time = moment().format('YYYY-MM-DD HH:mm')
|
|
|
- rwlcqd.find((p: any) => p.id == id).username = userName
|
|
|
- rwlcqd.find((p: any) => p.id == id).userid = userInfo?.id || ''
|
|
|
- rwlcqd.find((p: any) => p.id == id).type = 0
|
|
|
-
|
|
|
- // 进度
|
|
|
- let xmjd_json = JSON.parse(txbBidObject.value.c_xmjd_json || '[]')
|
|
|
- xmjd_json[5].create_time = moment().format('YYYY-MM-DD HH:mm')
|
|
|
- xmjd_json[5].username = userName
|
|
|
- xmjd_json[5].userid = userInfo?.id || ''
|
|
|
- xmjd_json[5].type = 0
|
|
|
- if (!xmjd_json[6]) {
|
|
|
- xmjd_json.push({ xmjd: id, type: 1, create_time: '', username: '', userid: '' })
|
|
|
- }
|
|
|
- const content = JSON.stringify({
|
|
|
- id: txbBidObject.value.id,
|
|
|
- rwlcqd: rwlcqd,
|
|
|
- c_xmjd_json: xmjd_json,
|
|
|
- })
|
|
|
- updateProject(COLUMN.TXB, MODEL.TXB, content)
|
|
|
- // 修改中标监控
|
|
|
- const steps = [
|
|
|
- { n: 1, label: '预警触发' },
|
|
|
- { n: 2, label: '投/续标准备' },
|
|
|
- { n: 3, label: '招标监控' },
|
|
|
- { n: 4, label: '标书制作' },
|
|
|
- { n: 5, label: '投标提交' },
|
|
|
- { n: 6, label: '开标监控' },
|
|
|
- { n: 7, label: '确认中标' },
|
|
|
- ]
|
|
|
- let json = xmjd_json.map((item: any) => {
|
|
|
- return {
|
|
|
- create_time: item.create_time ? item.create_time : moment().format('YYYY-MM-DD HH:mm'),
|
|
|
- desc: steps.find((s: any) => s.n == item.xmjd)?.label || '',
|
|
|
- username: item.username ? item.username : userName,
|
|
|
- userid: item.userid ? item.userid : userInfo?.id || '',
|
|
|
- }
|
|
|
- })
|
|
|
- const content2 = JSON.stringify({
|
|
|
- id: jkBidObject.value.id || '',
|
|
|
- c_gljg: finishBidObjectTemp.value?.flag ? finishBidObject.value?.id : '',
|
|
|
- c_jgjk_url: finishBidObjectTemp.value?.flag
|
|
|
- ? finishBidObject.value?.c_detail_url
|
|
|
- : finishBidObjectTemp.value?.url || '',
|
|
|
- c_lcsjx: json || '',
|
|
|
- c_sfzb: true,
|
|
|
- c_type: '中标登记',
|
|
|
- c_enable: false,
|
|
|
- })
|
|
|
- updateProject(COLUMN.KB_MONITOR, MODEL.KB_MONITOR, content2)
|
|
|
- } else if (addForm.value.type == '投续标中登记') {
|
|
|
- // 流程
|
|
|
- const rwlcqd = JSON.parse(selectedObject.value.rwlcqd || '[]')
|
|
|
- rwlcqd.forEach((p: any) => {
|
|
|
- if (!p.danger && p.id != 8) {
|
|
|
- // 未处理的流程全部重新处理
|
|
|
- ;(p.done = true),
|
|
|
- (p.create_time = moment().format('YYYY-MM-DD HH:mm')),
|
|
|
- (p.username = userName),
|
|
|
- (p.userid = userInfo?.id || ''),
|
|
|
- (p.type = 0)
|
|
|
- }
|
|
|
- })
|
|
|
- let xmjd_json = JSON.parse(selectedObject.value.c_xmjd_json || '[]')
|
|
|
- const curNumber = xmjd_json[xmjd_json.length - 1].xmjd
|
|
|
- for (let i = curNumber; i < 8; i++) {
|
|
|
- if (i == curNumber) {
|
|
|
- xmjd_json[i - 1].create_time = moment().format('YYYY-MM-DD HH:mm')
|
|
|
- xmjd_json[i - 1].username = userName
|
|
|
- xmjd_json[i - 1].userid = userInfo?.id || ''
|
|
|
- xmjd_json[i - 1].type = 0
|
|
|
- } else {
|
|
|
- if (i == 7) {
|
|
|
- xmjd_json.push({ xmjd: i, type: 1, create_time: '', username: '', userid: '' })
|
|
|
- } else {
|
|
|
- xmjd_json.push({
|
|
|
- xmjd: i,
|
|
|
- type: 0,
|
|
|
- create_time: moment().format('YYYY-MM-DD HH:mm'),
|
|
|
- username: userName,
|
|
|
- userid: userInfo?.id || '',
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- const steps = [
|
|
|
- { n: 1, label: '预警触发' },
|
|
|
- { n: 2, label: '投/续标准备' },
|
|
|
- { n: 3, label: '招标监控' },
|
|
|
- { n: 4, label: '标书制作' },
|
|
|
- { n: 5, label: '投标提交' },
|
|
|
- { n: 6, label: '开标监控' },
|
|
|
- { n: 7, label: '确认中标' },
|
|
|
- ]
|
|
|
- let json = xmjd_json.map((item: any) => {
|
|
|
- return {
|
|
|
- create_time: item.create_time ? item.create_time : moment().format('YYYY-MM-DD HH:mm'),
|
|
|
- desc: steps.find((s: any) => s.n == item.xmjd)?.label || '',
|
|
|
- username: item.username ? item.username : userName,
|
|
|
- userid: item.userid ? item.userid : userInfo?.id || '',
|
|
|
- }
|
|
|
- })
|
|
|
+const handleTypeChange = (val: any) => {
|
|
|
+ addForm.value.type = val || '新项目登记'
|
|
|
+ addForm.value.txbId = ''
|
|
|
+ selectedTxb.value = null
|
|
|
+ parentProject.value = null
|
|
|
+ parentCascader.value = []
|
|
|
+ if (val === '新项目登记') {
|
|
|
+ addForm.value.c_is_xb = false
|
|
|
+ }
|
|
|
+ // 切换类型只改显隐,不应带出整表必填红字
|
|
|
+ nextTick(() => {
|
|
|
+ formCompRef.value?.formRef?.clearValidate()
|
|
|
+ })
|
|
|
+}
|
|
|
|
|
|
- // 开标监控
|
|
|
- let kbFormData = {
|
|
|
- title: selectedObject.value.title,
|
|
|
- content: selectedObject.value.content,
|
|
|
- c_zbbh: selectedObject.value.c_xgzb ? selectedObject.value.c_xgzb : addForm.value.zb_code,
|
|
|
- c_sfzb: true,
|
|
|
- c_jgjk_url: finishBidObjectTemp.value?.url || '',
|
|
|
- c_kbsj: selectedObject.value.zbjzsj
|
|
|
- ? selectedObject.value.zbjzsj
|
|
|
- : addForm.value.zb_enddate,
|
|
|
- c_xmmc: selectedObject.value.c_xmbt,
|
|
|
- c_zbtjr: selectedObject.value.tbrq ? selectedObject.value.tbrq : addForm.value.tb_date,
|
|
|
- c_tbbj: selectedObject.value.tbbj ? selectedObject.value.tbbj : addForm.value.tb_money,
|
|
|
- c_glxm: selectedObject.value.xmbh,
|
|
|
- c_lcsjx: json || '',
|
|
|
- c_type: '中标登记',
|
|
|
- c_enable: false,
|
|
|
- }
|
|
|
+/** 用投续标 xmbh(原项目父编号)匹配父级在管,并回填级联 [区名, 项目id] */
|
|
|
+const matchParentByXmbh = (xmbh: string) => {
|
|
|
+ const guid = String(xmbh || '').trim()
|
|
|
+ if (!guid) {
|
|
|
+ parentProject.value = null
|
|
|
+ parentCascader.value = []
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ const parent =
|
|
|
+ finishProjects.value.find((p) => String(p.c_guid) === guid) ||
|
|
|
+ (props.areaProject as any[])
|
|
|
+ .flatMap((d: any) => d.children || [])
|
|
|
+ .find((c: any) => String(c.c_guid) === guid)
|
|
|
+ if (!parent) {
|
|
|
+ parentProject.value = null
|
|
|
+ parentCascader.value = []
|
|
|
+ ElMessage.warning('未找到投续标关联的父级在管项目,请手动选择')
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ parentProject.value = parent
|
|
|
+ // 在区→项目级联中定位路径,驱动「父级在管项目」展示
|
|
|
+ let path: any[] | null = null
|
|
|
+ for (const district of props.areaProject as any[]) {
|
|
|
+ const child = (district.children || []).find(
|
|
|
+ (c: any) =>
|
|
|
+ String(c.c_guid) === guid ||
|
|
|
+ String(c.value) === String(parent.id) ||
|
|
|
+ String(c.id) === String(parent.id)
|
|
|
+ )
|
|
|
+ if (child) {
|
|
|
+ path = [district.value, child.value]
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!path && parent.c_sq) {
|
|
|
+ const district = (props.areaProject as any[]).find(
|
|
|
+ (d: any) => d.label && String(d.label).includes(String(parent.c_sq))
|
|
|
+ )
|
|
|
+ if (district) {
|
|
|
+ const child = (district.children || []).find((c: any) => String(c.c_guid) === guid)
|
|
|
+ if (child) path = [district.value, child.value]
|
|
|
+ else if (parent.id != null) path = [district.value, parent.id]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ parentCascader.value = path || []
|
|
|
+ fillFromParent(parent)
|
|
|
+ return true
|
|
|
+}
|
|
|
|
|
|
- const res = await addContentParams(kbFormData, COLUMN.KB_MONITOR, MODEL.KB_MONITOR)
|
|
|
- let desc = {
|
|
|
- zb_project_code: selectedObject.value.c_xgzb
|
|
|
- ? selectedObject.value.c_xgzb
|
|
|
- : addForm.value.zb_code,
|
|
|
- zb_source_name: addForm.value.zb_source,
|
|
|
- zb_project_name: addForm.value.zb_name,
|
|
|
- zb_budget_amount: selectedObject.value.tbbj
|
|
|
- ? selectedObject.value.tbbj
|
|
|
- : addForm.value.tb_money,
|
|
|
- zb_detail_url: finishBidObjectTemp.value?.url || '',
|
|
|
- zb_publish_time: selectedObject.value.zbkssj
|
|
|
- ? selectedObject.value.zbkssj
|
|
|
- : addForm.value.zb_startdate,
|
|
|
- zb_bid_deadline: selectedObject.value.zbjzsj
|
|
|
- ? selectedObject.value.zbjzsj
|
|
|
- : addForm.value.zb_enddate,
|
|
|
- zb_author: userName,
|
|
|
- }
|
|
|
- let areaArr = (areaObject.value as any)?.pathLabels || []
|
|
|
- let tbFormData = {
|
|
|
- id: selectedObject.value.id || '',
|
|
|
- c_zgfw: selectedObject.value.c_zgfw ? selectedObject.value.c_zgfw : addFormZgfw.value,
|
|
|
- c_xgzb: selectedObject.value.c_xgzb ? selectedObject.value.c_xgzb : addForm.value.zb_code,
|
|
|
- c_xgjk: (res as any).content || '',
|
|
|
- c_xmbtqc: selectedObject.value.c_xmbt,
|
|
|
- c_qx: selectedObject.value.c_qx ? selectedObject.value.c_qx : areaArr[0] || '',
|
|
|
- c_xmbt: selectedObject.value.c_xmbt,
|
|
|
- c_xmjd_json: xmjd_json,
|
|
|
- zbxmbh: selectedObject.value.c_xgzb ? selectedObject.value.c_xgzb : addForm.value.zb_code,
|
|
|
- tbrq: selectedObject.value.tbrq ? selectedObject.value.tbrq : addForm.value.tb_date,
|
|
|
- tbbj: selectedObject.value.tbbj ? selectedObject.value.tbbj : addForm.value.tb_money,
|
|
|
- zbkssj: selectedObject.value.zbkssj
|
|
|
- ? selectedObject.value.zbkssj
|
|
|
- : addForm.value.zb_startdate,
|
|
|
- zbjzsj: selectedObject.value.zbjzsj
|
|
|
- ? selectedObject.value.zbjzsj
|
|
|
- : addForm.value.zb_enddate,
|
|
|
- rwlcqd: rwlcqd,
|
|
|
- zbmsxx: selectedObject.value.zbmsx ? selectedObject.value.zbmsx : desc,
|
|
|
- c_ytfw: selectedObject.value.ytfxw ? selectedObject.value.ytfxw : addFormYT.value,
|
|
|
- c_fwlx: selectedObject.value.fwlx
|
|
|
- ? selectedObject.value.fwlx
|
|
|
- : addFormFwlx.value.toString(),
|
|
|
- c_glqy: selectedObject.value.glqy ? selectedObject.value.glqy : areaArr[1] || '',
|
|
|
- }
|
|
|
- updateProject(COLUMN.TXB, MODEL.TXB, JSON.stringify(tbFormData))
|
|
|
- } else {
|
|
|
- // 流程
|
|
|
- const rwlcqd = CONFIG.TASKLIST
|
|
|
- rwlcqd.forEach((p: any) => {
|
|
|
- if (!p.danger && p.id != 8) {
|
|
|
- // 未处理的流程全部重新处理
|
|
|
- ;(p.done = true),
|
|
|
- (p.create_time = moment().format('YYYY-MM-DD HH:mm')),
|
|
|
- (p.username = userName),
|
|
|
- (p.userid = userInfo?.id || ''),
|
|
|
- (p.type = 0)
|
|
|
- }
|
|
|
- })
|
|
|
- let xmjd_json = []
|
|
|
- for (let i = 1; i < 8; i++) {
|
|
|
- if (i == 7) {
|
|
|
- xmjd_json.push({ xmjd: i, type: 1, create_time: '', username: '', userid: '' })
|
|
|
- } else {
|
|
|
- xmjd_json.push({
|
|
|
- xmjd: i,
|
|
|
- type: 0,
|
|
|
- create_time: moment().format('YYYY-MM-DD HH:mm'),
|
|
|
- username: userName,
|
|
|
- userid: userInfo?.id || '',
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- const steps = [
|
|
|
- { n: 1, label: '预警触发' },
|
|
|
- { n: 2, label: '投/续标准备' },
|
|
|
- { n: 3, label: '招标监控' },
|
|
|
- { n: 4, label: '标书制作' },
|
|
|
- { n: 5, label: '投标提交' },
|
|
|
- { n: 6, label: '开标监控' },
|
|
|
- { n: 7, label: '确认中标' },
|
|
|
- ]
|
|
|
- let json = xmjd_json.map((item: any) => {
|
|
|
- return {
|
|
|
- create_time: item.create_time ? item.create_time : moment().format('YYYY-MM-DD HH:mm'),
|
|
|
- desc: steps.find((s: any) => s.n == item.xmjd)?.label || '',
|
|
|
- username: item.username ? item.username : userName,
|
|
|
- userid: item.userid ? item.userid : userInfo?.id || '',
|
|
|
- }
|
|
|
- })
|
|
|
- // 开标监控
|
|
|
- let kbFormData = {
|
|
|
- title: finishObject.value.title,
|
|
|
- content: finishObject.value.content,
|
|
|
- c_zbbh: addForm.value.zb_code,
|
|
|
- c_sfzb: true,
|
|
|
- c_jgjk_url: finishBidObjectTemp.value?.url || '',
|
|
|
- c_kbsj: addForm.value.zb_enddate,
|
|
|
- c_xmmc: finishObject.value.c_xmmc,
|
|
|
- c_zbtjr: addForm.value.tb_date,
|
|
|
- c_tbbj: addForm.value.tb_money,
|
|
|
- c_glxm: finishObject.value.c_guid,
|
|
|
- c_lcsjx: json || '',
|
|
|
- c_type: '中标登记',
|
|
|
- c_enable: false,
|
|
|
- }
|
|
|
- const res = await addContentParams(kbFormData, COLUMN.KB_MONITOR, MODEL.KB_MONITOR)
|
|
|
- let desc = {
|
|
|
- zb_project_code: addForm.value.zb_code,
|
|
|
- zb_source_name: addForm.value.zb_source,
|
|
|
- zb_project_name: addForm.value.zb_name,
|
|
|
- zb_budget_amount: addForm.value.tb_money,
|
|
|
- zb_detail_url: finishBidObjectTemp.value?.url || '',
|
|
|
- zb_publish_time: addForm.value.zb_startdate,
|
|
|
- zb_bid_deadline: addForm.value.zb_enddate,
|
|
|
- zb_author: userName,
|
|
|
- }
|
|
|
- let areaArr = (areaObject.value as any)?.pathLabels || []
|
|
|
- let tbFormData = {
|
|
|
- title: finishObject.value.title,
|
|
|
- content: finishObject.value.content,
|
|
|
- c_sfzb: finishObject.value.c_htqyjf,
|
|
|
- c_zgfw: addFormZgfw.value ? addFormZgfw.value : finishObject.value.c_wtfs || '',
|
|
|
- c_kssj: moment(finishObject.value.c_zgxmhtksrq).format('YYYY-MM-DD HH:mm') || '',
|
|
|
- c_dqsj: moment(finishObject.value.c_zgxmhtdqrq).format('YYYY-MM-DD HH:mm') || '',
|
|
|
- xmbh: finishObject.value.c_guid,
|
|
|
- c_nh: finishObject.value.c_nhhtsr || '',
|
|
|
- c_is_xb: addForm.value.c_is_xb,
|
|
|
- c_xgzb: addForm.value.zb_code,
|
|
|
- c_xgjk: (res as any).content || '',
|
|
|
- c_xmbtqc: finishObject.value.c_xmmc,
|
|
|
- c_qx: areaArr[0] ? areaArr[0] : finishObject.value.c_sq || '',
|
|
|
- c_xmbt: finishObject.value.c_xmmc,
|
|
|
- c_xmjd_json: xmjd_json,
|
|
|
- zbxmbh: addForm.value.zb_code,
|
|
|
- tbrq: addForm.value.tb_date,
|
|
|
- tbbj: addForm.value.tb_money,
|
|
|
- zbkssj: addForm.value.zb_startdate,
|
|
|
- zbjzsj: addForm.value.zb_enddate,
|
|
|
- rwlcqd: rwlcqd,
|
|
|
- zbmsxx: desc,
|
|
|
- c_ytfw: addFormYT.value,
|
|
|
- c_fwlx: addFormFwlx.value.toString(),
|
|
|
- c_glqy: areaArr[1] ? areaArr[1] : finishObject.value.c_glqynbkj || '',
|
|
|
- }
|
|
|
- await addContentParams(tbFormData, COLUMN.TXB, MODEL.TXB)
|
|
|
- }
|
|
|
+const handleTxbChange = (id: any) => {
|
|
|
+ const row = txbList.value.find((t) => t.id === id)
|
|
|
+ selectedTxb.value = row || null
|
|
|
+ parentProject.value = null
|
|
|
+ parentCascader.value = []
|
|
|
+ if (!row) return
|
|
|
+ addForm.value.c_is_xb = !!row.c_is_xb
|
|
|
+ addForm.value.c_xmmc = row.c_xmbtqc || row.c_xmbt || row.title || ''
|
|
|
+ addForm.value.c_htqyjf = row.c_fbz || ''
|
|
|
+ // 续标:用投续标「原项目父编号」xmbh 自动匹配父级在管项目
|
|
|
+ if (row.c_is_xb) {
|
|
|
+ if (row.xmbh) {
|
|
|
+ matchParentByXmbh(row.xmbh)
|
|
|
} else {
|
|
|
+ ElMessage.warning('该投续标为续标但未关联原项目编号,请手动选择父级在管项目')
|
|
|
}
|
|
|
-
|
|
|
- close()
|
|
|
- })
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-const addContentParams = async (formData: any, columnId: number, modelId: number) => {
|
|
|
- const params = {
|
|
|
- content: JSON.stringify(formData),
|
|
|
- columnId: columnId,
|
|
|
- modelId: modelId,
|
|
|
+const handleXBSwitchChange = (val: any) => {
|
|
|
+ if (addForm.value.type === '进行中投续标') return
|
|
|
+ addForm.value.c_is_xb = !!val
|
|
|
+ if (!val) {
|
|
|
+ parentCascader.value = []
|
|
|
+ parentProject.value = null
|
|
|
}
|
|
|
- const res = await api.addContent(params)
|
|
|
- return res
|
|
|
}
|
|
|
|
|
|
-const handleTypeChange = (val: any) => {
|
|
|
- addForm.value.title = ''
|
|
|
- addForm.value.type = val || ''
|
|
|
+const handleParentCascaderChange = (val: any) => {
|
|
|
+ parentCascader.value = val || []
|
|
|
+ const tempObj = finishTreeProjects.value.find((item: any) =>
|
|
|
+ String(item.id).includes(String(val?.[1]))
|
|
|
+ )
|
|
|
+ parentProject.value = tempObj || null
|
|
|
+ if (tempObj) fillFromParent(tempObj)
|
|
|
}
|
|
|
|
|
|
-const selectedObject = ref<any>({})
|
|
|
-const handleProjectChange = async (val: any) => {
|
|
|
- addForm.value.title = val.title || ''
|
|
|
- jkBidObject.value = null
|
|
|
- txbBidObject.value = null
|
|
|
- finishBidObject.value = null
|
|
|
- if (addForm.value.type == '监控中未中标') {
|
|
|
- jkBidObject.value = val
|
|
|
- const res = await getTxbBidContent(COLUMN.TXB, val.id, 'c_xgjk')
|
|
|
- txbBidObject.value = res || {}
|
|
|
- } else {
|
|
|
- selectedObject.value = val
|
|
|
+const fillFromParent = (p: any) => {
|
|
|
+ if (!addForm.value.c_xmmc) addForm.value.c_xmmc = p.c_xmmc || ''
|
|
|
+ if (!addForm.value.c_xmdz) addForm.value.c_xmdz = p.c_xmdz || ''
|
|
|
+ if (!addForm.value.c_htqyjf) addForm.value.c_htqyjf = p.c_htqyjf || ''
|
|
|
+ addForm.value.c_htmj =
|
|
|
+ p.c_htmj != null && p.c_htmj !== '' ? Number(p.c_htmj) : addForm.value.c_htmj
|
|
|
+ addForm.value.c_htzj =
|
|
|
+ p.c_hte != null && p.c_hte !== ''
|
|
|
+ ? Number(p.c_hte)
|
|
|
+ : p.c_htzj != null && p.c_htzj !== ''
|
|
|
+ ? Number(p.c_htzj)
|
|
|
+ : addForm.value.c_htzj
|
|
|
+ if (p.c_hzyt) {
|
|
|
+ addForm.value.c_hzyt = p.c_hzyt
|
|
|
+ addFormYT.value = p.c_hzyt
|
|
|
+ }
|
|
|
+ if (p.c_wtfs != null && p.c_wtfs !== '') {
|
|
|
+ addFormZgfw.value = String(p.c_wtfs)
|
|
|
+ addForm.value.c_wtfs = String(p.c_wtfs)
|
|
|
+ }
|
|
|
+ if (p.c_jffs != null && p.c_jffs !== '') {
|
|
|
+ addFormJffs.value = String(p.c_jffs)
|
|
|
+ addForm.value.c_jffs = String(p.c_jffs)
|
|
|
+ }
|
|
|
+ if (p.c_fkms != null && p.c_fkms !== '') {
|
|
|
+ addFormFkms.value = String(p.c_fkms)
|
|
|
+ addForm.value.c_fkms = String(p.c_fkms)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-const getTypeProjects = async (columnId: number) => {
|
|
|
- const params: any = {
|
|
|
- columnId: columnId,
|
|
|
- orderBy: JSON.stringify([{ field: 'update_time', orderByType: 2 }]),
|
|
|
- states: '0,1,2,3,4',
|
|
|
- pageSize: 9999,
|
|
|
- page: 0,
|
|
|
- }
|
|
|
- const res = await getDmsDataList(params)
|
|
|
- return (res as any).content
|
|
|
+const handleNodeAreaClick = () => {
|
|
|
+ const nodes = (formCompRef.value?.areaCascader as any)?.getCheckedNodes?.() || []
|
|
|
+ if (!nodes.length) return
|
|
|
+ const leaf = nodes[nodes.length - 1]
|
|
|
+ const path = leaf?.pathValues || addFormArea.value
|
|
|
+ areaCodes.value = Array.isArray(path) ? [...path] : []
|
|
|
+ const district = (props.glArea as any[]).find((d: any) => d.value === areaCodes.value[0])
|
|
|
+ const part = district?.children?.find((c: any) => c.value === areaCodes.value[1])
|
|
|
+ addForm.value.c_glqynbkj = part?.label || leaf?.label || ''
|
|
|
+ addForm.value.c_sfzxs = district?.provinceName || addForm.value.c_sfzxs || '上海市'
|
|
|
+ addForm.value.c_sq = district?.cityName || addForm.value.c_sq || ''
|
|
|
}
|
|
|
|
|
|
-const getDmsDataList = async (params: any) => {
|
|
|
- return await api.getDmsDataList(params)
|
|
|
+const clearTenderUpload = () => {
|
|
|
+ tenderFileRaw.value = null
|
|
|
+ tenderFilePath.value = ''
|
|
|
+ addForm.value.tenderFile = null
|
|
|
}
|
|
|
|
|
|
-const updateProject = async (columnId: number, modelId: number, content: string) => {
|
|
|
- const params: any = {
|
|
|
- columnId: columnId,
|
|
|
- modelId: modelId,
|
|
|
- content: content,
|
|
|
+const handleTenderFileChange = async (file: any) => {
|
|
|
+ if (!file) {
|
|
|
+ clearTenderUpload()
|
|
|
+ formCompRef.value?.formRef?.validateField?.('tenderFile')
|
|
|
+ return
|
|
|
}
|
|
|
- const res = await api.updateContent(params)
|
|
|
- if ((res as any).code === 200) {
|
|
|
- // ElMessage.success('添加成功')
|
|
|
- initData()
|
|
|
- } else {
|
|
|
- // ElMessage.error('添加失败')
|
|
|
+ const raw: File | undefined = file?.raw
|
|
|
+ if (!raw) return
|
|
|
+
|
|
|
+ tenderFileRaw.value = raw
|
|
|
+ tenderFilePath.value = ''
|
|
|
+ addForm.value.tenderFile = file
|
|
|
+ tenderUploading.value = true
|
|
|
+ const loading = ElLoading.service({
|
|
|
+ lock: true,
|
|
|
+ text: '标书上传并校验中,文件较大请耐心等待…',
|
|
|
+ background: 'rgba(0, 0, 0, 0.7)',
|
|
|
+ })
|
|
|
+ try {
|
|
|
+ const result = await uploadAndVerifyFile(raw, COLUMN.SOURCE)
|
|
|
+ if (!result.ok) {
|
|
|
+ clearTenderUpload()
|
|
|
+ ElMessage.error(result.message)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ tenderFilePath.value = result.filePath
|
|
|
+ ElMessage.success(result.message || '标书上传并校验通过')
|
|
|
+ } catch (e: any) {
|
|
|
+ clearTenderUpload()
|
|
|
+ ElMessage.error(e?.message || '标书上传失败')
|
|
|
+ } finally {
|
|
|
+ loading.close()
|
|
|
+ tenderUploading.value = false
|
|
|
+ formCompRef.value?.formRef?.validateField?.('tenderFile')
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-const handleXBSwitchChange = (val: any) => {
|
|
|
- addForm.value.c_is_xb = val
|
|
|
+const putDateTime = (content: Record<string, any>, key: string, value: string) => {
|
|
|
+ if (!value) return
|
|
|
+ const m = moment(value)
|
|
|
+ if (!m.isValid()) return
|
|
|
+ content[key] = m.valueOf()
|
|
|
}
|
|
|
|
|
|
-/** 获取投续标内容 */
|
|
|
-const getTxbBidContent = async (columnId: number, search: string, type: string) => {
|
|
|
- const params: any = {
|
|
|
- columnId: columnId,
|
|
|
- orderBy: JSON.stringify([{ field: 'update_time', orderByType: 2 }]),
|
|
|
- states: '0,1,2,3,4',
|
|
|
+const findLatestSourceByGuidPrefix = async (prefix: string) => {
|
|
|
+ const res = await api.getDmsDataList({
|
|
|
+ columnId: COLUMN.SOURCE,
|
|
|
+ states: '0,1,2,3',
|
|
|
pageSize: 1,
|
|
|
page: 0,
|
|
|
- }
|
|
|
- if (search) {
|
|
|
- params.search = JSON.stringify([
|
|
|
- ...(params.search ? JSON.parse(params.search) : []),
|
|
|
- {
|
|
|
- field: type,
|
|
|
- searchType: 1,
|
|
|
- content: { value: search },
|
|
|
- },
|
|
|
- ])
|
|
|
- }
|
|
|
- const res = await getDmsDataList(params)
|
|
|
- return (res as any).content.data[0]
|
|
|
+ orderBy: JSON.stringify([{ field: 'update_time', orderByType: 2 }]),
|
|
|
+ search: JSON.stringify([
|
|
|
+ { field: 'c_guid', searchType: 2, content: { value: `%${prefix}%` } },
|
|
|
+ ]),
|
|
|
+ })
|
|
|
+ if ((res as any).code === 200) return (res as any).content.data?.[0] || null
|
|
|
+ return null
|
|
|
}
|
|
|
|
|
|
-const handleNodeAreaClick = () => {
|
|
|
- const nodes = (formCompRef.value?.areaCascader as any)?.getCheckedNodes?.() || []
|
|
|
- if (nodes.length) {
|
|
|
- const targetNode = nodes[nodes.length - 1]
|
|
|
- areaObject.value = targetNode
|
|
|
- }
|
|
|
+/** 按字段模糊查栏目内容 */
|
|
|
+const findContentsByField = async (columnId: number, field: string, value: string) => {
|
|
|
+ const res = await api.getDmsDataList({
|
|
|
+ columnId,
|
|
|
+ states: '0,1,2,3',
|
|
|
+ pageSize: 50,
|
|
|
+ page: 0,
|
|
|
+ search: JSON.stringify([
|
|
|
+ { field, searchType: 2, content: { value: `%${value}%` } },
|
|
|
+ ]),
|
|
|
+ })
|
|
|
+ if ((res as any)?.code === 200) return (res as any).content?.data || []
|
|
|
+ return []
|
|
|
}
|
|
|
|
|
|
-const handleAdminCascaderChange = (val: any) => {
|
|
|
- const tempObj = finishTreeProjects.value.filter((item: any) => item.id.includes(val[1]))[0]
|
|
|
- finishObject.value = tempObj
|
|
|
+/** 中标登记收口:关联招标监控 c_gl_xm=投续标 id → c_complete/c_enable */
|
|
|
+const closeRelatedZbMonitors = async (txbId: string | number) => {
|
|
|
+ const rows = await findContentsByField(COLUMN.ZB_MONITOR, 'c_gl_xm', String(txbId))
|
|
|
+ for (const row of rows) {
|
|
|
+ if (!row?.id) continue
|
|
|
+ const res = await api.updateContent({
|
|
|
+ columnId: String(COLUMN.ZB_MONITOR),
|
|
|
+ modelId: String(MODEL.ZB_MONITOR),
|
|
|
+ content: JSON.stringify({
|
|
|
+ id: row.id,
|
|
|
+ c_complete: true,
|
|
|
+ c_enable: true,
|
|
|
+ }),
|
|
|
+ } as any)
|
|
|
+ if ((res as any)?.code !== 200) {
|
|
|
+ ElMessage.warning('项目已创建,但关联招标监控收口失败')
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
-</script>
|
|
|
|
|
|
-<style scoped>
|
|
|
-.bid-content-page {
|
|
|
- width: 100%;
|
|
|
+/** 中标登记收口:改关联开标监控(不新增) */
|
|
|
+const updateRelatedKbMonitor = async (opts: {
|
|
|
+ kbId: string | number
|
|
|
+ xmmc: string
|
|
|
+ glxm: string
|
|
|
+}) => {
|
|
|
+ const res = await api.updateContent({
|
|
|
+ columnId: String(COLUMN.KB_MONITOR),
|
|
|
+ modelId: String(MODEL.KB_MONITOR),
|
|
|
+ content: JSON.stringify({
|
|
|
+ id: opts.kbId,
|
|
|
+ c_sfzb: true,
|
|
|
+ c_xmmc: opts.xmmc,
|
|
|
+ c_glxm: opts.glxm,
|
|
|
+ c_type: '中标登记',
|
|
|
+ c_enable: false,
|
|
|
+ c_sfts: true,
|
|
|
+ c_tssj: moment().format('YYYY-MM-DD HH:mm:ss'),
|
|
|
+ }),
|
|
|
+ } as any)
|
|
|
+ if ((res as any)?.code !== 200) {
|
|
|
+ ElMessage.warning('项目已创建,但关联开标监控更新失败')
|
|
|
+ }
|
|
|
}
|
|
|
-.bid-container {
|
|
|
- height: calc(100vh - 180px);
|
|
|
- overflow-y: auto;
|
|
|
+
|
|
|
+const submitForm = () => {
|
|
|
+ const formEl = formCompRef.value?.formRef
|
|
|
+ if (!formEl) return
|
|
|
+ // 同步业态/字典到表单
|
|
|
+ addForm.value.c_hzyt = addFormYT.value || addForm.value.c_hzyt
|
|
|
+ addForm.value.c_wtfs = addFormZgfw.value
|
|
|
+ addForm.value.c_jffs = addFormJffs.value
|
|
|
+ addForm.value.c_fkms = addFormFkms.value
|
|
|
+
|
|
|
+ formEl.validate(async (valid) => {
|
|
|
+ if (!valid) return
|
|
|
+ if (!tenderFilePath.value) {
|
|
|
+ ElMessage.error('请先上传并通过校验的项目标书')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!areaCodes.value || areaCodes.value.length < 2) {
|
|
|
+ // 尝试从 addFormArea 取
|
|
|
+ if (addFormArea.value?.length >= 2) {
|
|
|
+ areaCodes.value = [...addFormArea.value]
|
|
|
+ handleNodeAreaClick()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!areaCodes.value || areaCodes.value.length < 2) {
|
|
|
+ ElMessage.error('请选择管理区域(用于生成项目编码)')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (addForm.value.c_is_xb && !parentProject.value?.c_guid) {
|
|
|
+ ElMessage.error('续标必须选择父级在管项目')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (addForm.value.type === '进行中投续标' && !selectedTxb.value) {
|
|
|
+ ElMessage.error('请选择进行中投续标')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const ytcode =
|
|
|
+ ytList.value.find((item: any) => item.c_yt_name === addForm.value.c_hzyt)?.c_yt_code || ''
|
|
|
+ if (!ytcode) {
|
|
|
+ ElMessage.error('所选业态缺少业态编码,无法生成项目编码')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ submitting.value = true
|
|
|
+ try {
|
|
|
+ const hasFather = !!addForm.value.c_is_xb
|
|
|
+ const prefix = `${areaCodes.value[0]}${areaCodes.value[1]}${moment().format('YYYYMMDD')}${ytcode}`
|
|
|
+ const latest = await findLatestSourceByGuidPrefix(prefix)
|
|
|
+ const c_guid = nextSourceGuidFromLatest(latest?.c_guid, {
|
|
|
+ districtCode: areaCodes.value[0],
|
|
|
+ partCode: areaCodes.value[1],
|
|
|
+ ytCode: ytcode,
|
|
|
+ hasFather,
|
|
|
+ })
|
|
|
+
|
|
|
+ const content: any = {
|
|
|
+ title: c_guid,
|
|
|
+ content: c_guid,
|
|
|
+ c_guid,
|
|
|
+ c_father_code: hasFather ? parentProject.value.c_guid : '',
|
|
|
+ c_xmmc: addForm.value.c_xmmc,
|
|
|
+ c_xmdz: addForm.value.c_xmdz,
|
|
|
+ c_htqyjf: addForm.value.c_htqyjf,
|
|
|
+ c_glqynbkj: addForm.value.c_glqynbkj,
|
|
|
+ c_sq: addForm.value.c_sq,
|
|
|
+ c_sfzxs: addForm.value.c_sfzxs || '上海市',
|
|
|
+ c_htmj: addForm.value.c_htmj ?? '',
|
|
|
+ c_htbh: addForm.value.c_htbh,
|
|
|
+ // 表单「合同额」双写 c_hte + c_htzj(元)
|
|
|
+ c_hte:
|
|
|
+ addForm.value.c_htzj != null && addForm.value.c_htzj !== ('' as any)
|
|
|
+ ? String(addForm.value.c_htzj)
|
|
|
+ : '',
|
|
|
+ c_htzj:
|
|
|
+ addForm.value.c_htzj != null && addForm.value.c_htzj !== ('' as any)
|
|
|
+ ? String(addForm.value.c_htzj)
|
|
|
+ : '',
|
|
|
+ c_bndhtys: addForm.value.c_bndhtys ?? '',
|
|
|
+ c_hzyt: addForm.value.c_hzyt,
|
|
|
+ c_wtfs: addForm.value.c_wtfs,
|
|
|
+ c_jffs: addForm.value.c_jffs,
|
|
|
+ c_fkms: addForm.value.c_fkms,
|
|
|
+ c_hts: addForm.value.c_hts,
|
|
|
+ c_xms: addForm.value.c_xms,
|
|
|
+ c_bcxyzj: addForm.value.c_bcxyzj,
|
|
|
+ c_zbdfqk: addForm.value.c_zbdfqk,
|
|
|
+ // 选文件时已上传并通过校验的路径
|
|
|
+ c_history_tender: tenderFilePath.value,
|
|
|
+ }
|
|
|
+ putDateTime(content, 'c_zgxmhtksrq', addForm.value.c_zgxmhtksrq)
|
|
|
+ putDateTime(content, 'c_zgxmhtdqrq', addForm.value.c_zgxmhtdqrq)
|
|
|
+ putDateTime(content, 'c_xmkssj', addForm.value.c_xmkssj)
|
|
|
+ putDateTime(content, 'c_xmdqsj', addForm.value.c_xmdqsj)
|
|
|
+
|
|
|
+ const addRes = await api.addContent({
|
|
|
+ content: JSON.stringify(content),
|
|
|
+ columnId: COLUMN.SOURCE,
|
|
|
+ modelId: MODEL.SOURCE,
|
|
|
+ })
|
|
|
+ if ((addRes as any)?.code !== 200) {
|
|
|
+ ElMessage.error((addRes as any)?.message || '新建项目失败')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const newId = (addRes as any).content
|
|
|
+ if (!newId) {
|
|
|
+ ElMessage.error('新建项目未返回内容 ID')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 进行中投续标:终止原流程,并收口关联招标/开标监控
|
|
|
+ if (addForm.value.type === '进行中投续标' && selectedTxb.value?.id) {
|
|
|
+ const term = await api.updateContent({
|
|
|
+ columnId: String(COLUMN.TXB),
|
|
|
+ modelId: String(MODEL.TXB),
|
|
|
+ content: JSON.stringify({
|
|
|
+ id: selectedTxb.value.id,
|
|
|
+ c_terminated: true,
|
|
|
+ c_sfwc: true,
|
|
|
+ c_scxxmglid: String(newId),
|
|
|
+ }),
|
|
|
+ } as any)
|
|
|
+ if ((term as any)?.code !== 200) {
|
|
|
+ ElMessage.warning('项目已创建,但投续标终止状态写入失败')
|
|
|
+ }
|
|
|
+
|
|
|
+ // 已在招标监控:关联 ZB(c_gl_xm=投续标 id)→ 完成并启用
|
|
|
+ await closeRelatedZbMonitors(selectedTxb.value.id)
|
|
|
+
|
|
|
+ // 已在开标监控:改关联 KB(TXB.c_xgjk),不新增
|
|
|
+ if (selectedTxb.value.c_xgjk) {
|
|
|
+ await updateRelatedKbMonitor({
|
|
|
+ kbId: selectedTxb.value.c_xgjk,
|
|
|
+ xmmc: addForm.value.c_xmmc,
|
|
|
+ glxm: hasFather ? parentProject.value?.c_guid || c_guid : c_guid,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 新项目登记:无关联开标监控,写一条归档痕迹
|
|
|
+ await api.addContent({
|
|
|
+ content: JSON.stringify({
|
|
|
+ title: addForm.value.c_xmmc,
|
|
|
+ content: addForm.value.c_xmmc,
|
|
|
+ c_sfzb: true,
|
|
|
+ c_xmmc: addForm.value.c_xmmc,
|
|
|
+ c_glxm: hasFather ? parentProject.value?.c_guid || c_guid : c_guid,
|
|
|
+ c_type: '中标登记',
|
|
|
+ c_enable: false,
|
|
|
+ c_sfts: true,
|
|
|
+ c_tssj: moment().format('YYYY-MM-DD HH:mm:ss'),
|
|
|
+ }),
|
|
|
+ columnId: COLUMN.KB_MONITOR,
|
|
|
+ modelId: MODEL.KB_MONITOR,
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ ElMessage.success('中标登记成功,已生成新在管项目')
|
|
|
+ addForm.value = emptySourceForm()
|
|
|
+ clearTenderUpload()
|
|
|
+ selectedTxb.value = null
|
|
|
+ parentProject.value = null
|
|
|
+ parentCascader.value = []
|
|
|
+ addFormArea.value = []
|
|
|
+ areaCodes.value = []
|
|
|
+ await initData()
|
|
|
+ close()
|
|
|
+ } catch (e) {
|
|
|
+ console.error(e)
|
|
|
+ ElMessage.error('中标登记失败')
|
|
|
+ } finally {
|
|
|
+ submitting.value = false
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
-</style>
|
|
|
+</script>
|