更新商机管理 财务管理 项目管理功能

This commit is contained in:
jia 2023-12-14 09:37:31 +08:00
parent fbac82a43c
commit ec78fa5a6c
65 changed files with 5657 additions and 803 deletions

View File

@ -24,3 +24,9 @@ export function apiCustomerDemandSolutionDelete(params: any) {
export function apiCustomerDemandSolutionDetail(params: any) {
return request.get({ url: '/custom.customer_demand_solution/detail', params })
}
//获取某个项目id的客户需求列表
export function getListByProjectId(params: any) {
return request.get({ url: '/custom.customer_demand/getListByProjectId', params })
}

32
src/api/projecttype.ts Normal file
View File

@ -0,0 +1,32 @@
import request from '@/utils/request'
// 项目类型表列表
export function apiProjecttypeLists(params: any) {
return request.get({ url: '/project.project_type_set/lists', params })
}
// 添加项目类型
export function apiProjecttypeAdd(params: any) {
return request.post({ url: '/project.project_type_set/add', params })
}
// 编辑项目类型
export function apiProjecttypeEdit(params: any) {
return request.post({ url: '/project.project_type_set/edit', params })
}
// 删除项目类型
export function apiProjecttypeDelete(params: any) {
return request.post({ url: '/project.project_type_set/delete', params })
}
// 项目类型详情
export function apiProjectDelete(params: any) {
return request.post({ url: '/project.project_type_set/detail', params })
}
//获取所有项目类型
export function getAllProjectTypes(params: any) {
return request.post({ url: '/project.project_type_set/getAllProjectTypes', params })
}

View File

@ -0,0 +1,92 @@
<template>
<div>
<el-card class="!border-none" shadow="never">
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="客户名称" prop="name">
<el-input class="w-[280px]" v-model="queryParams.name" clearable placeholder="请输入客户名称" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
<div class="mt-4">
<el-table :data="pager.lists" @cell-click="handleCurrentChange">
<el-table-column label="客户名称" prop="bid_document_no" show-overflow-tooltip />
<el-table-column label="项目名称" prop="bid_document_no" show-overflow-tooltip />
<el-table-column label="标书编号" prop="bid_document_no" show-overflow-tooltip />
<el-table-column label="招标公司名称" width="120" prop="invite_tenders_company_name" show-overflow-tooltip />
<el-table-column label="投标公司名称" width="120" prop="bid_company_name" show-overflow-tooltip />
<el-table-column label="购买人员" prop="buyer" show-overflow-tooltip />
<el-table-column label="购买标书金额" width="120" prop="amount" show-overflow-tooltip />
<el-table-column label="招标项目资金来源" width="150" prop="project_fund_source">
<template #default="{ row }">
<dict-value :options="dictData.construction_funds_sources" :value="row.project_fund_source" />
</template>
</el-table-column>
<el-table-column label="投标时间" prop="bid_date">
<template #default="{ row }">
<span>{{ row.bid_date ? row.bid_date : '' }}</span>
</template>
</el-table-column>
<el-table-column label="购买标书时间" prop="buy_date" width="120">
<template #default="{ row }">
<span>{{ row.buy_date ? row.buy_date : '' }}</span>
</template>
</el-table-column>
<el-table-column label="招标方式" prop="invite_tenders_type" width="100">
<template #default="{ row }">
<dict-value :options="dictData.bidding_method" :value="row.invite_tenders_type" />
</template>
</el-table-column>
<el-table-column label="投标地址" prop="bid_address" show-overflow-tooltip width="100" />
<el-table-column label="是否需要保证金" prop="is_margin">
<template #default="{ row }">
<dict-value :options="dictData.whether_status" :value="row.is_margin" />
</template>
</el-table-column>
<el-table-column label="保证金金额" prop="margin_amount" width="100" show-overflow-tooltip />
<!-- <el-table-column label="招标项目慨况" prop="bid_project_overview" show-overflow-tooltip />
<el-table-column label="项目简介" prop="project_desc" show-overflow-tooltip />
<el-table-column label="附件" prop="annex" show-overflow-tooltip /> -->
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { usePaging } from "@/hooks/usePaging"
import { useDictData } from "@/hooks/useDictOptions"
import { apiBidBuyBiddingDocumentLists } from '@/api/bid_buy_bidding_document'
import { defineEmits } from "vue"
//
const queryParams = reactive({
name: ''
});
//
const { dictData } = useDictData('construction_funds_sources,bidding_method,whether_status')
//
const emits = defineEmits(["customEvent"]);
//
const handleCurrentChange = (value: any) => {
emits("customEvent", value);
};
//
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: apiBidBuyBiddingDocumentLists,
params: queryParams,
});
getLists();
</script>

View File

@ -14,7 +14,7 @@
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
<div class="mt-4">
<el-table :data="pager.lists" @cell-click="handleCurrentChange">
<el-table-column label="序号" property="name" />
<el-table-column label="序号" type="index" />
<el-table-column label="年份 " property="custom_type" />
<el-table-column label="一级科目" property="credit_rating" />
<el-table-column label="二级科目" property="province_name" />

View File

@ -0,0 +1,64 @@
<template>
<div>
<el-card class="!border-none" shadow="never">
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="客户名称" prop="name">
<el-input class="w-[280px]" v-model="queryParams.name" clearable placeholder="请输入姓名" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
<div class="mt-4">
<el-table :data="pager.lists" @cell-click="handleCurrentChange">
<el-table-column type="selection" width="55" />
<el-table-column label="组织" prop="custom_id" show-overflow-tooltip />
<el-table-column label="姓名" prop="name" show-overflow-tooltip />
<el-table-column label="职位" prop="position" show-overflow-tooltip />
<el-table-column label="手机" prop="phone" show-overflow-tooltip />
<el-table-column label="电话" prop="telephone" show-overflow-tooltip />
<el-table-column label="邮箱" prop="email" show-overflow-tooltip />
<el-table-column label="备注" prop="notes" show-overflow-tooltip />
<el-table-column label="状态" prop="status" show-overflow-tooltip />
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { usePaging } from "@/hooks/usePaging"
import { useDictData } from "@/hooks/useDictOptions"
import { apiCustomContactsLists } from '@/api/custom_contacts'
import { defineEmits } from "vue"
//
const queryParams = reactive({
name: ''
});
//
const emits = defineEmits(["customEvent"]);
//
const handleCurrentChange = (value: any) => {
emits("customEvent", value);
};
//
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: apiCustomContactsLists,
params: queryParams,
});
getLists();
</script>

View File

@ -15,11 +15,15 @@
<div class="mt-4">
<el-table :data="pager.lists" @cell-click="handleCurrentChange">
<el-table-column label="客户名称" property="name" />
<el-table-column label="客户属性" property="custom_type" />
<el-table-column label="客户属性" prop="custom_type">
<template #default="{ row }">
<dict-value :options="dictData.custom_type" :value="row.custom_type" />
</template>
</el-table-column>
<el-table-column label="信用度" property="credit_rating" />
<el-table-column label="省" property="province_name" />
<!-- <el-table-column label="省" property="province_name" />
<el-table-column label="市" property="city_name" />
<el-table-column label="区" property="street_name" />
<el-table-column label="区" property="street_name" /> -->
<el-table-column label="主联系人" property="master_name" />
<el-table-column label="联系方式" property="master_phone" />
</el-table>
@ -43,7 +47,8 @@ const queryParams = reactive({
name: ''
});
//
const { dictData } = useDictData('custom_type')
//
const emits = defineEmits(["customEvent"]);

View File

@ -0,0 +1,73 @@
<template>
<div>
<el-card class="!border-none" shadow="never">
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="查询" prop="name">
<el-input class="w-[280px]" v-model="queryParams.name" clearable placeholder="请输入内容" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
<div class="mt-4">
<el-table :data="pager.lists" @cell-click="handleCurrentChange">
<el-table-column label="序号" type="index" />
<el-table-column label="客户名称" prop="custom_name" show-overflow-tooltip />
<el-table-column label="项目名称" prop="project_name" show-overflow-tooltip />
<el-table-column label="项目编码" prop="project_code" show-overflow-tooltip />
<el-table-column label="需求主题" prop="theme" show-overflow-tooltip />
<el-table-column label="客户需求提供人" prop="supplier" show-overflow-tooltip />
<el-table-column label="提供人联系方式" prop="supplier_contacts" show-overflow-tooltip />
<el-table-column label="重要程度" prop="importance_text" show-overflow-tooltip />
<el-table-column label="记录时间" prop="recording_time" show-overflow-tooltip />
<el-table-column label="需求内容" prop="demand_content" show-overflow-tooltip />
<el-table-column label="附件" prop="annex" show-overflow-tooltip />
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
</div>
</template>
<script lang="ts" setup>
import { usePaging } from "@/hooks/usePaging"
import { useDictData } from "@/hooks/useDictOptions"
import { getListByProjectId } from '@/api/customer_demand_solution'
import { defineEmits } from "vue"
import { timeFormat } from '@/utils/util'
const props = defineProps({
productid: {
type: String
}
})
//
const queryParams = reactive({
project_id: props.productid,
});
const { dictData } = useDictData('project_type,project_content,bidding_method,relationship,information_sources,construction_funds_sources,construction_financial_status,construction_recognition,my_construction_recognition,strategic_significance,industry,unit_nature')
//
const emits = defineEmits(["customEvent"]);
//
const handleCurrentChange = (value: any) => {
emits("customEvent", value);
};
//
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: getListByProjectId,
params: queryParams,
});
getLists();
</script>

View File

@ -15,7 +15,7 @@
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
<div class="mt-4">
<el-table :data="pager.lists" @cell-click="handleCurrentChange">
<el-table-column label="序号" property="name" />
<el-table-column label="序号" type="index" />
<el-table-column label="项目名称" prop="name" show-overflow-tooltip />
<el-table-column label="项目编码" prop="project_code" show-overflow-tooltip />
<el-table-column label="项目类型" prop="project_type">
@ -23,7 +23,6 @@
<dict-value :options="dictData.project_type" :value="row.project_type" />
</template>
</el-table-column>
<el-table-column label="项目所在地" prop="project_address" show-overflow-tooltip />
<el-table-column label="战略意义" prop="strategic_significance">
<template #default="{ row }">

View File

@ -14,6 +14,7 @@
</template>
<script lang="ts" setup>
const props = defineProps({
list: {
type: Array
}

View File

@ -0,0 +1,204 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="投标决策详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="160px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="客户名称">
{{ formData.custom_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目名称">
{{ formData.project.name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目编码">
{{ formData.project.project_code }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目估算(万元)">
{{ formData.project_estimation }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="投标时间">
{{ formData.bidding_time }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="购买标书时间">
{{ formData.buy_bid_document_date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="招标项目资金来源">
<dict-value :options="dictData.construction_funds_sources" :value="formData.bidding_project_fund_source" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="招标方式">
<dict-value :options="dictData.bidding_method" :value="formData.bid_type" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="竞争对手">
{{ formData.competitor }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="保证金金额">
{{ formData.margin_amount }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否需要保证金">
<dict-value :options="dictData.whether_status" :value="formData.whether_status" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="保证金金额">
{{ formData.competitor }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="开标日期">
{{ formData.bid_opening_date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="保证金退还时间">
{{ formData.margin_amount_return_date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="有无内部资源">
<dict-value :options="dictData.whether_status" :value="formData.is_internal_resources" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目把握度">
{{ formData.project_assurancee }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="招标项目概况">
{{ formData.bid_project_overview }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目简介">
{{ formData.project_desc }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
// for (const key in formData) {
// if (data[key] != null && data[key] != undefined) {
// //@ts-ignore
// formData[key] = data[key]
// }
// }
Object.assign(formData, data)
console.log(formData, '2222222222')
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -4,17 +4,17 @@
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
<el-row>
<el-col :span="8">
<el-form-item label="项目名称" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.project_id" clearable placeholder="请输入" />
<el-form-item label="项目名称" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]" @click="showDialog = true">
<el-input v-model="project_name" readonly clearable placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="项目编码" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.project_id" clearable placeholder="请输入" />
<el-input v-model="project_code" clearable readonly placeholder="请输入" />
</el-form-item></el-col>
<el-col :span="8">
<el-form-item label="客户名称" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.project_id" clearable placeholder="请输入" />
<el-input v-model="matsname" clearable readonly placeholder="请输入" />
</el-form-item></el-col><el-col :span="8">
<el-form-item label="项目估算" prop="project_estimation" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.project_estimation" clearable placeholder="请输入项目估算" />
@ -101,6 +101,10 @@
</el-form>
<reviewprocess />
</popup>
<el-dialog v-model="showDialog" title="选择项目" width="70%">
<projectTable @customEvent="customEvent"></projectTable>
</el-dialog>
</div>
</template>
@ -108,6 +112,9 @@
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import reviewprocess from '@/components/reviewprocess/index.vue'
import projectTable from "@/components/project/index.vue"
import { apiBidBiddingDecisionAdd, apiBidBiddingDecisionEdit, apiBidBiddingDecisionDetail } from '@/api/bid_bidding_decision'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
@ -117,10 +124,14 @@ defineProps({
default: () => ({})
}
})
const matsname = ref('')
const project_name = ref('')
const project_code = ref('')
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const showDialog = ref(false)
import configs from "@/config"
const base_url = configs.baseUrl + configs.urlPrefix
import useUserStore from "@/stores/modules/user";
@ -143,7 +154,14 @@ const handleAvatarSuccess_four = (
const delFileFn = (index: number) => {
formData.annex.splice(index, 1)
}
//
const customEvent = (e: any) => {
formData.project_id = e.id;
matsname.value = e.person
project_name.value = e.custom_name
project_code.value = e.project_code
showDialog.value = false;
};
//
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑投标决策' : '新增投标决策'
@ -180,6 +198,9 @@ const formRules = reactive<any>({
//
const setFormData = async (data: Record<any, any>) => {
matsname.value = data.project.person
project_name.value = data.project.name
project_code.value = data.project.project_code
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore

View File

@ -67,7 +67,7 @@
</template>
</el-table-column>
<el-table-column label="项目把握度" prop="project_assurance" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button v-perms="['bid.bid_bidding_decision/edit']" type="primary" link @click="handleEdit(row)">
编辑
@ -75,6 +75,9 @@
<el-button v-perms="['bid.bid_bidding_decision/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['bid.bid_bidding_decision/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -83,6 +86,7 @@
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
@ -90,15 +94,18 @@
<script lang="ts" setup name="bidBiddingDecisionLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiBidBiddingDecisionLists, apiBidBiddingDecisionDelete } from '@/api/bid_bidding_decision'
import { apiBidBiddingDecisionLists, apiBidBiddingDecisionDelete, apiBidBiddingDecisionDetail } from '@/api/bid_bidding_decision'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -133,10 +140,11 @@ const handleAdd = async () => {
//
const handleEdit = async (data: any) => {
let res = await apiBidBiddingDecisionDetail({ id: data.id })
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
editRef.value?.setFormData(res)
}
//
@ -145,7 +153,15 @@ const handleDelete = async (id: number | any[]) => {
await apiBidBiddingDecisionDelete({ id })
getLists()
}
//
const handledetail = async (data: any) => {
let res = await apiBidBiddingDecisionDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,193 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="购买标书详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="160px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="客户名称">
{{ formData.custom_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目名称">
{{ formData.project.name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目编码">
{{ formData.project.project_code }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="购买标书金额">
{{ formData.amount }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="购买人员">
{{ formData.buyer }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="投标时间">
{{ formData.bidding_time }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="购买标书时间">
{{ formData.buy_date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="招标项目资金来源">
<dict-value :options="dictData.construction_funds_sources" :value="formData.project_fund_source" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="招标方式">
<dict-value :options="dictData.bidding_method" :value="formData.invite_tenders_type" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="保证金金额">
{{ formData.margin_amount }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否需要保证金">
<dict-value :options="dictData.whether_status" :value="formData.is_margin" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="投标时间">
{{ formData.bid_date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="投标地址">
{{ formData.bid_address }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="招标项目概况">
{{ formData.bid_project_overview }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目简介">
{{ formData.project_desc }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
// for (const key in formData) {
// if (data[key] != null && data[key] != undefined) {
// //@ts-ignore
// formData[key] = data[key]
// }
// }
Object.assign(formData, data)
console.log(formData, '2222222222')
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -4,16 +4,18 @@
<el-form ref="formRef" :model="formData" label-width="130px" :rules="formRules">
<el-row>
<el-col :span="8">
<el-form-item label="项目名称" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.project_id" clearable placeholder="请输入" />
</el-form-item></el-col><el-col :span="8">
<el-form-item label="项目编码" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.project_id" clearable placeholder="请输入" />
</el-form-item></el-col><el-col :span="8">
<el-form-item label="客户名称" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.project_id" clearable placeholder="请输入" />
<el-form-item label="项目名称" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]" @click="showDialog = true">
<el-input v-model="project_name" readonly clearable placeholder="请输入" />
</el-form-item>
</el-col><el-col :span="8">
</el-col>
<el-col :span="8">
<el-form-item label="项目编码" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="project_code" clearable readonly placeholder="请输入" />
</el-form-item></el-col>
<el-col :span="8">
<el-form-item label="客户名称" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="matsname" clearable readonly placeholder="请输入" />
</el-form-item></el-col><el-col :span="8">
<el-form-item label="招标公司名称" prop="invite_tenders_company_name" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.invite_tenders_company_name" clearable placeholder="请输入招标公司名称" />
</el-form-item></el-col><el-col :span="8">
@ -91,6 +93,10 @@
</el-form>
<reviewprocess />
</popup>
<el-dialog v-model="showDialog" title="选择项目" width="70%">
<projectTable @customEvent="customEvent"></projectTable>
</el-dialog>
</div>
</template>
@ -98,6 +104,7 @@
import type { FormInstance } from 'element-plus'
import reviewprocess from '@/components/reviewprocess/index.vue'
import Popup from '@/components/popup/index.vue'
import projectTable from "@/components/project/index.vue"
import { apiBidBuyBiddingDocumentAdd, apiBidBuyBiddingDocumentEdit, apiBidBuyBiddingDocumentDetail } from '@/api/bid_buy_bidding_document'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
@ -107,6 +114,9 @@ defineProps({
default: () => ({})
}
})
const matsname = ref('')
const project_name = ref('')
const project_code = ref('')
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
@ -116,6 +126,7 @@ const base_url = configs.baseUrl + configs.urlPrefix
import useUserStore from "@/stores/modules/user";
const userStore = useUserStore();
const formannex = reactive([])
const showDialog = ref(false)
//
const handleAvatarSuccess_four = (
response,
@ -164,9 +175,19 @@ const formRules = reactive<any>({
})
//
const customEvent = (e: any) => {
formData.project_id = e.id;
matsname.value = e.person
project_name.value = e.custom_name
project_code.value = e.project_code
showDialog.value = false;
};
//
const setFormData = async (data: Record<any, any>) => {
matsname.value = data.project.person
project_name.value = data.project.name
project_code.value = data.project.project_code
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore

View File

@ -75,7 +75,7 @@
<!-- <el-table-column label="招标项目慨况" prop="bid_project_overview" show-overflow-tooltip />
<el-table-column label="项目简介" prop="project_desc" show-overflow-tooltip />
<el-table-column label="附件" prop="annex" show-overflow-tooltip /> -->
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button v-perms="['bid.bid_buy_bidding_document/edit']" type="primary" link @click="handleEdit(row)">
编辑
@ -83,6 +83,9 @@
<el-button v-perms="['bid.bid_buy_bidding_document/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['bid.bid_buy_bidding_document/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -91,6 +94,7 @@
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
@ -98,15 +102,19 @@
<script lang="ts" setup name="bidBuyBiddingDocumentLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiBidBuyBiddingDocumentLists, apiBidBuyBiddingDocumentDelete } from '@/api/bid_buy_bidding_document'
import { apiBidBuyBiddingDocumentLists, apiBidBuyBiddingDocumentDelete, apiBidBuyBiddingDocumentDetail } from '@/api/bid_buy_bidding_document'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -142,10 +150,11 @@ const handleAdd = async () => {
//
const handleEdit = async (data: any) => {
let res = await apiBidBuyBiddingDocumentDetail({ id: data.id })
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
editRef.value?.setFormData(res)
}
//
@ -154,7 +163,15 @@ const handleDelete = async (id: number | any[]) => {
await apiBidBuyBiddingDocumentDelete({ id })
getLists()
}
//
const handledetail = async (data: any) => {
let res = await apiBidBuyBiddingDocumentDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,185 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="投标决策详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="160px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="开标时间">
{{ formData.bid_opening_dat }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="购买标书时间">
{{ formData.buy_bid_document_date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否需要保证金">
<dict-value :options="dictData.whether_status" :value="formData.is_need_deposit" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="金额">
{{ formData.business_review_total_amount }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="招标项目概况">
{{ formData.bidding_project_overview }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="保证金退还时间">
{{ formData.deposit_refund_time }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="技术协议偏差">
{{ formData.technical_protocol_deviation }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="招标项目概况">
{{ formData.bidding_project_overview }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目简介">
{{ formData.project_introduction }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="税率">
{{ formData.pay_type }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="付款比例">
{{ formData.pay_rate }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="商务合同偏差">
{{ formData.business_contract_deviation }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="偏差处理方案">
{{ formData.business_contract_deviation_handling_plan }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="商务审查附件">
{{ formData.business_contract_deviation_annex }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
// for (const key in formData) {
// if (data[key] != null && data[key] != undefined) {
// //@ts-ignore
// formData[key] = data[key]
// }
// }
Object.assign(formData, data)
console.log(formData, '2222222222')
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -1,117 +1,95 @@
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="550px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<popup ref="popupRef" :title="popupTitle" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" :rules="formRules" inline>
<el-row>
<el-col :span="12">
<el-form-item label="审批id" prop="approve_id">
<el-input v-model="formData.approve_id" clearable placeholder="请输入审批id" />
</el-form-item>
<el-form-item label="购买标书id" prop="buy_bidding_document_id">
<el-input v-model="formData.buy_bidding_document_id" clearable placeholder="请输入购买标书id" />
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="购买标书" prop="buy_bidding_document_id" @click="showDialog = true">
<el-input v-model="bidding_name" clearable readonly placeholder="请输入购买标书" />
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="是否需要保证金" prop="is_need_deposit">
<el-radio-group v-model="formData.is_need_deposit" placeholder="请选择是否需要保证金">
<el-radio
v-for="(item, index) in dictData.whether_status"
:key="index"
:label="parseInt(item.value)"
>
<el-radio v-for="(item, index) in dictData.whether_status" :key="index" :label="parseInt(item.value)">
{{ item.name }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="开标日期" prop="bid_opening_date">
<el-date-picker
class="flex-1 !flex"
v-model="formData.bid_opening_date"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择开标日期">
<el-date-picker class="flex-1 !flex" v-model="formData.bid_opening_date" clearable type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择开标日期">
</el-date-picker>
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="保证金退还时间" prop="deposit_refund_time">
<el-date-picker
class="flex-1 !flex"
v-model="formData.deposit_refund_time"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择保证金退还时间">
<el-date-picker class="flex-1 !flex" v-model="formData.deposit_refund_time" clearable type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择保证金退还时间">
</el-date-picker>
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="招标项目概况" prop="bidding_project_overview">
<el-input v-model="formData.bidding_project_overview" clearable placeholder="请输入招标项目概况" />
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="项目简介" prop="project_introduction">
<el-input v-model="formData.project_introduction" clearable placeholder="请输入项目简介" />
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="附件" prop="annex">
<el-input v-model="formData.annex" clearable placeholder="请输入附件" />
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="技术协议偏差" prop="technical_protocol_deviation">
<el-input v-model="formData.technical_protocol_deviation" clearable placeholder="请输入技术协议偏差" />
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="协议偏差处理方案" prop="protocol_deviation_handling_plan">
<el-input v-model="formData.protocol_deviation_handling_plan" clearable placeholder="请输入协议偏差处理方案" />
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="技术审查附件" prop="technical_review_annex">
<el-input v-model="formData.technical_review_annex" clearable placeholder="请输入技术审查附件" />
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="总金额" prop="business_review_total_amount">
<el-input v-model="formData.business_review_total_amount" clearable placeholder="请输入总金额" />
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="税率" prop="tax_rate">
<el-select class="flex-1" v-model="formData.tax_rate" clearable placeholder="请选择税率">
<el-option
v-for="(item, index) in dictData.tax_rate"
:key="index"
:label="item.name"
:value="parseInt(item.value)"
/>
<el-option v-for="(item, index) in dictData.tax_rate" :key="index" :label="item.name" :value="parseInt(item.value)" />
</el-select>
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="付款方式" prop="pay_type">
<el-select class="flex-1" v-model="formData.pay_type" clearable placeholder="请选择付款方式">
<el-option
v-for="(item, index) in dictData.pay_type"
:key="index"
:label="item.name"
:value="parseInt(item.value)"
/>
<el-option v-for="(item, index) in dictData.pay_type" :key="index" :label="item.name" :value="parseInt(item.value)" />
</el-select>
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="付款比例" prop="pay_rate">
<el-input v-model="formData.pay_rate" clearable placeholder="请输入付款比例" />
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="商务合同偏差" prop="business_contract_deviation">
<el-input v-model="formData.business_contract_deviation" clearable placeholder="请输入商务合同偏差" />
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="偏差处理方案" prop="business_contract_deviation_handling_plan">
<el-input v-model="formData.business_contract_deviation_handling_plan" clearable placeholder="请输入偏差处理方案" />
</el-form-item>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="商务审查附件" prop="business_contract_deviation_annex">
<el-input v-model="formData.business_contract_deviation_annex" clearable placeholder="请输入商务审查附件" />
</el-form-item>
</el-form-item></el-col>
</el-row>
</el-form>
</popup>
<el-dialog v-model="showDialog" title="选择标书" width="70%">
<biddocumentTable @customEvent="customEvent"></biddocumentTable>
</el-dialog>
</div>
</template>
<script lang="ts" setup name="bidDocumentExaminationEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import biddocumentTable from "@/components/biddocument/index.vue"
import { apiBidDocumentExaminationAdd, apiBidDocumentExaminationEdit, apiBidDocumentExaminationDetail } from '@/api/bid_document_examination'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
@ -122,8 +100,8 @@ const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const showDialog = ref(false)
const bidding_name = ref('')
//
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑标书审查' : '新增标书审查'
@ -152,7 +130,13 @@ const formData = reactive({
business_contract_deviation_annex: '',
})
//
const customEvent = (e: any) => {
formData.buy_bidding_document_id = e.id;
bidding_name.value = e.bid_company_name
showDialog.value = false
};
//
const formRules = reactive<any>({

View File

@ -1,11 +1,7 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form
class="mb-[-16px]"
:model="queryParams"
inline
>
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="购买标书id" prop="buy_bidding_document_id">
<el-input class="w-[280px]" v-model="queryParams.buy_bidding_document_id" clearable placeholder="请输入购买标书id" />
</el-form-item>
@ -22,11 +18,7 @@
</template>
新增
</el-button>
<el-button
v-perms="['bid.bid_document_examination/delete']"
:disabled="!selectData.length"
@click="handleDelete(selectData)"
>
<el-button v-perms="['bid.bid_document_examination/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
@ -70,24 +62,17 @@
<el-table-column label="商务合同偏差" prop="business_contract_deviation" show-overflow-tooltip />
<el-table-column label="偏差处理方案" prop="business_contract_deviation_handling_plan" show-overflow-tooltip />
<el-table-column label="商务审查附件" prop="business_contract_deviation_annex" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button
v-perms="['bid.bid_document_examination/edit']"
type="primary"
link
@click="handleEdit(row)"
>
<el-button v-perms="['bid.bid_document_examination/edit']" type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button
v-perms="['bid.bid_document_examination/delete']"
type="danger"
link
@click="handleDelete(row.id)"
>
<el-button v-perms="['bid.bid_document_examination/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['bid.bid_document_examination/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -96,6 +81,7 @@
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
@ -103,15 +89,24 @@
<script lang="ts" setup name="bidDocumentExaminationLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiBidDocumentExaminationLists, apiBidDocumentExaminationDelete } from '@/api/bid_document_examination'
import {
apiBidDocumentExaminationLists, apiBidDocumentExaminationDelete,
apiBidDocumentExaminationDetail
} from '@/api/bid_document_examination'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
import projectTable from "@/components/project/index.vue"
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -156,7 +151,14 @@ const handleDelete = async (id: number | any[]) => {
await apiBidDocumentExaminationDelete({ id })
getLists()
}
//
const handledetail = async (data: any) => {
let res = await apiBidDocumentExaminationDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,204 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="投标决策详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="160px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="客户名称">
{{ formData.custom_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目名称">
{{ formData.project.name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目编码">
{{ formData.project.project_code }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目估算(万元)">
{{ formData.project_estimation }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="投标时间">
{{ formData.bidding_time }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="购买标书时间">
{{ formData.buy_bid_document_date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="招标项目资金来源">
<dict-value :options="dictData.construction_funds_sources" :value="formData.bidding_project_fund_source" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="招标方式">
<dict-value :options="dictData.bidding_method" :value="formData.bid_type" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="竞争对手">
{{ formData.competitor }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="保证金金额">
{{ formData.margin_amount }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否需要保证金">
<dict-value :options="dictData.whether_status" :value="formData.whether_status" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="保证金金额">
{{ formData.competitor }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="开标日期">
{{ bid_opening_date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="保证金退还时间">
{{ formData.margin_amount_return_date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="有无内部资源">
<dict-value :options="dictData.whether_status" :value="formData.is_internal_resources" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目把握度">
{{ formData.project_assurancee }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="招标项目概况">
{{ formData.bid_project_overview }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目简介">
{{ formData.project_desc }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
// for (const key in formData) {
// if (data[key] != null && data[key] != undefined) {
// //@ts-ignore
// formData[key] = data[key]
// }
// }
Object.assign(formData, data)
console.log(formData, '2222222222')
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -1,19 +1,12 @@
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="550px"
@confirm="handleSubmit"
@close="handleClose"
>
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-form-item label="标书审查id" prop="bid_document_examination_id">
<el-form-item label="标书审查id" prop="bid_document_examination_id" @click="showDialog = true">
<el-input v-model="formData.bid_document_examination_id" clearable placeholder="请输入标书审查id" />
</el-form-item>
<el-form-item label="产品id" prop="product_id">
<el-input v-model="formData.product_id" clearable placeholder="请输入产品id" />
<el-form-item label="产品id" prop="product_id" @click="showDialog1 = true">
<el-input v-model="formData.product_id" readonly clearable placeholder="请输入产品id" />
</el-form-item>
<el-form-item label="产品数量" prop="product_num">
<el-input v-model="formData.product_num" clearable placeholder="请输入产品数量" />
@ -38,14 +31,24 @@
</el-form-item>
</el-form>
</popup>
<el-dialog v-model="showDialog" title="选择标书" width="70%">
<biddocumentTable @customEvent="customEvent"></biddocumentTable>
</el-dialog>
<el-dialog v-model="showDialog1" title="选择产品" width="70%">
<prodctTable @customEvent="customEvent1"></prodctTable>
</el-dialog>
</div>
</template>
<script lang="ts" setup name="bidDocumentExaminationDetailEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import biddocumentTable from "@/components/biddocument/index.vue"
import prodctTable from "@/components/product/index.vue"
import { apiBidDocumentExaminationDetailAdd, apiBidDocumentExaminationDetailEdit, apiBidDocumentExaminationDetailDetail } from '@/api/bid_document_examination_detail'
import { timeFormat } from '@/utils/util'
import projectTable from "@/components/project/index.vue"
import type { PropType } from 'vue'
defineProps({
dictData: {
@ -84,7 +87,22 @@ const formRules = reactive<any>({
})
//
const customEvent = (e: any) => {
formData.buy_bidding_document_id = e.id;
bidding_name.value = e.custom_name
};
//
const customEvent1 = (e: any) => {
formData.buy_bidding_document_id = e.id;
bidding_name.value = e.custom_name
};
//
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {

View File

@ -1,11 +1,7 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form
class="mb-[-16px]"
:model="queryParams"
inline
>
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="标书审查id" prop="bid_document_examination_id">
<el-input class="w-[280px]" v-model="queryParams.bid_document_examination_id" clearable placeholder="请输入标书审查id" />
</el-form-item>
@ -25,11 +21,7 @@
</template>
新增
</el-button>
<el-button
v-perms="['bid.bid_document_examination_detail/delete']"
:disabled="!selectData.length"
@click="handleDelete(selectData)"
>
<el-button v-perms="['bid.bid_document_examination_detail/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
@ -44,24 +36,17 @@
<el-table-column label="报价单价" prop="unit_price" show-overflow-tooltip />
<el-table-column label="报价金额" prop="total_amount" show-overflow-tooltip />
<el-table-column label="" prop="create_user" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button
v-perms="['bid.bid_document_examination_detail/edit']"
type="primary"
link
@click="handleEdit(row)"
>
<el-button v-perms="['bid.bid_document_examination_detail/edit']" type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button
v-perms="['bid.bid_document_examination_detail/delete']"
type="danger"
link
@click="handleDelete(row.id)"
>
<el-button v-perms="['bid.bid_document_examination_detail/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['bid.bid_document_examination_detail/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -70,6 +55,7 @@
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
@ -77,15 +63,19 @@
<script lang="ts" setup name="bidDocumentExaminationDetailLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiBidDocumentExaminationDetailLists, apiBidDocumentExaminationDetailDelete } from '@/api/bid_document_examination_detail'
import { apiBidDocumentExaminationDetailLists, apiBidDocumentExaminationDetailDelete, apiBidDocumentExaminationDetailDetail } from '@/api/bid_document_examination_detail'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -131,7 +121,15 @@ const handleDelete = async (id: number | any[]) => {
await apiBidDocumentExaminationDetailDelete({ id })
getLists()
}
//
const handledetail = async (data: any) => {
let res = await apiBidDocumentExaminationDetailDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,150 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="投标结果详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="160px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="客户名称">
{{ formData.custom.name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目名称">
{{ formData.project.name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目编码">
{{ formData.project.project_code }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否中标">
{{ formData.is_successful }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="中标单位">
{{ formData.bidder_amount }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="中标金额">
{{ formData.bidder_amount }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="投标总结">
{{ formData.bid_summary }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
// for (const key in formData) {
// if (data[key] != null && data[key] != undefined) {
// //@ts-ignore
// formData[key] = data[key]
// }
// }
Object.assign(formData, data)
console.log(formData, '2222222222')
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -1,19 +1,18 @@
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="550px"
@confirm="handleSubmit"
@close="handleClose"
>
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-form-item label="标书审查id" prop="bid_document_examination_id">
<el-input v-model="formData.bid_document_examination_id" clearable placeholder="请输入标书审查id" />
</el-form-item>
<el-form-item label="项目id" prop="project_id">
<el-input v-model="formData.project_id" clearable placeholder="请输入项目id" />
<el-form-item label="项目名称" prop="project_id">
<el-input v-model="project_name" readonly clearable placeholder="请选择项目" />
</el-form-item>
<el-form-item label="项目编码" prop="project_id">
<el-input v-model="project_code" readonly clearable placeholder="请选择项目" />
</el-form-item>
<el-form-item label="客户名称" prop="project_id">
<el-input v-model="project_matername" readonly clearable placeholder="请选择项目" />
</el-form-item>
<el-form-item label="是否中标" prop="is_successful">
<el-input v-model="formData.is_successful" clearable placeholder="请输入是否中标" />
@ -35,12 +34,21 @@
</el-form-item>
</el-form>
</popup>
<el-dialog v-model="showDialog" title="选择标书" width="70%">
<biddocumentTable @customEvent="customEvent"></biddocumentTable>
</el-dialog>
<el-dialog v-model="showDialog1" title="选择产品" width="70%">
<prodctTable @customEvent="customEvent1"></prodctTable>
</el-dialog>
</div>
</template>
<script lang="ts" setup name="bidResultEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import biddocumentTable from "@/components/biddocument/index.vue"
import prodctTable from "@/components/product/index.vue"
import { apiBidResultAdd, apiBidResultEdit, apiBidResultDetail } from '@/api/bid_result'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
@ -54,8 +62,9 @@ const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const project_matername = ref('')
const project_name = ref('')
const project_code = ref('')
//
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑投标结果' : '新增投标结果'
@ -80,7 +89,22 @@ const formRules = reactive<any>({
})
//
const customEvent = (e: any) => {
formData.buy_bidding_document_id = e.id;
bidding_name.value = e.custom_name
};
//
const customEvent1 = (e: any) => {
formData.buy_bidding_document_id = e.id;
bidding_name.value = e.custom_name
};
//
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {

View File

@ -1,11 +1,7 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form
class="mb-[-16px]"
:model="queryParams"
inline
>
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="标书审查id" prop="bid_document_examination_id">
<el-input class="w-[280px]" v-model="queryParams.bid_document_examination_id" clearable placeholder="请输入标书审查id" />
</el-form-item>
@ -25,11 +21,7 @@
</template>
新增
</el-button>
<el-button
v-perms="['bid.bid_result/delete']"
:disabled="!selectData.length"
@click="handleDelete(selectData)"
>
<el-button v-perms="['bid.bid_result/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
@ -43,22 +35,15 @@
<el-table-column label="中标金额大写" prop="bidder_amount_daxie" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button
v-perms="['bid.bid_result/edit']"
type="primary"
link
@click="handleEdit(row)"
>
<el-button v-perms="['bid.bid_result/edit']" type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button
v-perms="['bid.bid_result/delete']"
type="danger"
link
@click="handleDelete(row.id)"
>
<el-button v-perms="['bid.bid_result/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['bid.bid_result/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -67,6 +52,7 @@
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
@ -74,15 +60,17 @@
<script lang="ts" setup name="bidResultLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiBidResultLists, apiBidResultDelete } from '@/api/bid_result'
import { apiBidResultLists, apiBidResultDelete, apiBidResultDetail } from '@/api/bid_result'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -128,7 +116,15 @@ const handleDelete = async (id: number | any[]) => {
await apiBidResultDelete({ id })
getLists()
}
//
const handledetail = async (data: any) => {
let res = await apiBidResultDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,172 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="解决方案详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="组织">
{{ formData.org_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门">
{{ formData.dept_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目名称">
{{ formData.project_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户名称">
{{ formData.custom_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目编码">
{{ formData.project_code }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="需求名称">
{{ formData.customer_demand_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="竞争对手名称">
{{ formData.competitor_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="竞争对手联系人">
{{ formData.competitor_contacts }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系人电话">
{{ formData.competitor_contacts_phone }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="竞争能力">
{{ formData.competitive_power }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="竞争对手优势">
{{ formData.competitor_advantages }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="竞争对手劣势">
{{ formData.competitor_disadvantages }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注">
{{ formData.remark }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
Object.assign(formData, data)
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
// console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -1,42 +1,41 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-form-item label="组织id" prop="org_id">
<el-select class="flex-1" v-model="formData.org_id" clearable placeholder="请选择组织id">
<!-- <el-option
v-for="(item, index) in dictData."
:key="index"
:label="item.name"
:value="parseInt(item.value)"
/> -->
<popup ref="popupRef" :title="popupTitle" :async="true" width="650px" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
<el-form-item label="组织id" prop="org_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-select class="flex-1" v-model="formData.org_id" clearable placeholder="请选择组织id" @change="area_change">
<el-option v-for="(item, index) in orglist" :key="index" :label="item.name" :value="parseInt(item.id)" />
</el-select>
</el-form-item>
<el-form-item label="部门id" prop="department_id">
<el-select class="flex-1" v-model="formData.department_id" clearable placeholder="请选择部门id">
<!-- <el-option
v-for="(item, index) in dictData."
:key="index"
:label="item.name"
:value="parseInt(item.value)"
/> -->
<el-form-item label="部门id" prop="dept_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-select class="flex-1" v-model="formData.dept_id" clearable placeholder="请选择部门id">
<el-option v-for="(item, index) in jobs" :key="index" :label="item.name" :value="parseInt(item.id)" />
</el-select>
</el-form-item>
<el-form-item label="项目id" prop="project_id">
<el-input v-model="formData.project_id" clearable placeholder="请输入项目id" />
<el-form-item label="项目名称" prop="project_id" @click="showDialog = true" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="project_name" clearable placeholder="请输入项目名称" />
</el-form-item>
<el-form-item label="客户需求id" prop="customer_demand_id">
<el-input v-model="formData.customer_demand_id" clearable placeholder="请输入客户需求id" />
<el-form-item label="项目编码" prop="project_id">
<el-input v-model="project_code
" clearable placeholder="请输入项目编码" />
</el-form-item>
<el-form-item label="客户名称" prop="project_id">
<el-input v-model="custom_name
" clearable placeholder="请输入客户名称" />
</el-form-item>
<el-form-item label="需求名称" prop="customer_demand_id">
<el-input v-model="customer_demand_name" clearable placeholder="输入需求名称" @click="showDialog1 = true" />
</el-form-item>
<el-form-item label="竞争对手名称" prop="competitor_name">
<el-input v-model="formData.competitor_name" clearable placeholder="请输入竞争对手名称" />
<el-input v-model="formData.competitor_name" clearable placeholder="请输入竞争对手名称" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]" />
</el-form-item>
<el-form-item label="竞争对手联系人" prop="competitor_contacts">
<el-input v-model="formData.competitor_contacts" clearable placeholder="请输入竞争对手联系人" />
<el-input v-model="formData.competitor_contacts" clearable placeholder="请输入竞争对手联系人" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]" />
</el-form-item>
<el-form-item label="联系人电话" prop="competitor_contacts_phone">
<el-form-item label="联系人电话" prop="competitor_contacts_phone" :rules="[{ validator: checkPhone, trigger: 'blur' }]">
<el-input v-model="formData.competitor_contacts_phone" clearable placeholder="请输入联系人电话" />
</el-form-item>
<el-form-item label="竞争能力" prop="competitive_power">
<el-input v-model="formData.competitive_power" clearable placeholder="请输入竞争能力" />
</el-form-item>
@ -49,11 +48,29 @@
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" clearable placeholder="请输入备注" />
</el-form-item>
<el-form-item label="附件" prop="annex">
<el-input v-model="formData.annex" clearable placeholder="请输入附件" />
<el-form-item label="附件" prop="field127">
<el-upload accept=".pdf" class="upload-demo" :show-file-list="false" aria-hidden="true" :headers="{ Token: userStore.token }" :action="base_url + '/upload/file'" :on-success="handleAvatarSuccess_four" ref="upload">
<el-button type="primary">
上传
</el-button>
</el-upload>
<div>
<div v-for="(item, index) in formDataannex" style="margin-left: 5px;display: block;">
<a style="margin-left: 10px; color: #4a5dff; align-self: flex-start" :href="item.uri" target="_blank">{{ item.name }}</a>
<span style="cursor: pointer;margin-left: 5px;" @click="delFileFn(index)">x</span>
</div>
</div>
</el-form-item>
</el-form>
</popup>
<el-dialog v-model="showDialog" title="选择项目" width="70%">
<projectTable @customEvent="customEvent"></projectTable>
</el-dialog>
<el-dialog v-model="showDialog1" title="选择需求" width="70%">
<customerdemand @customEvent="customEvent1" :productid="formData.project_id"></customerdemand>
</el-dialog>
</div>
</template>
@ -62,6 +79,10 @@ import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCompetitorAdd, apiCompetitorEdit, apiCompetitorDetail } from '@/api/competitor'
import { timeFormat } from '@/utils/util'
import { deptAll } from '@/api/org/department'
import { getAll } from '@/api/org/organization'
import projectTable from "@/components/project/index.vue"
import customerdemand from "@/components/customerdemand/index.vue"
import type { PropType } from 'vue'
defineProps({
dictData: {
@ -72,9 +93,77 @@ defineProps({
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const orglist = reactive([])
const jobs = reactive([])
const project_name
= ref('')
const project_code
= ref('')
const custom_name
= ref('')
const customer_demand_name = ref('')
const formDataannex = reactive([])
import configs from "@/config"
const base_url = configs.baseUrl + configs.urlPrefix
import useUserStore from "@/stores/modules/user";
const userStore = useUserStore();
//
const handleAvatarSuccess_four = (
response,
uploadFile
) => {
if (response.code == 0) {
ElMessage.error(response.msg);
return;
}
formDataannex.push(
{ uri: response.data.uri, name: response.data.name }
);
};
//
const delFileFn = (index: number) => {
formDataannex.splice(index, 1)
}
// dialog
const showDialog = ref(false)
const showDialog1 = ref(false)
const customEvent = (e: any) => {
formData.project_id = e.id;
project_name.value = e.name;
project_code
.value = e.project_code;
custom_name
.value = e.custom_name;
showDialog.value = false;
};
const customEvent1 = (e: any) => {
formData.customer_demand_id = e.id;
customer_demand_name.value = e.theme;
showDialog1.value = false;
};
const getlista = () => {
getAll().then((res) => {
// orglist = res.data
Object.assign(orglist, res)
})
}
const area_change = (e: any) => {
formData.org_id = e
let data = { 'org_id': e }
// console.log(data)
deptAll(data).then((res) => {
Object.assign(jobs, res)
})
}
//
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑竞争对手' : '新增竞争对手'
@ -84,7 +173,7 @@ const popupTitle = computed(() => {
const formData = reactive({
id: '',
org_id: '',
department_id: '',
dept_id: '',
project_id: '',
customer_demand_id: '',
competitor_name: '',
@ -97,7 +186,20 @@ const formData = reactive({
annex: '',
})
const checkPhone = (rule: any, value: any, callback: (arg0: Error) => any) => {
const phoneReg = /^1[3|4|5|7|8][0-9]{9}$/
// if (!value) {
// return callback(new Error(''))
// }
setTimeout(() => {
if (phoneReg.test(value)) {
callback()
} else {
callback(new Error('电话号码格式不正确'))
}
}, 100)
}
//
const formRules = reactive<any>({
@ -106,6 +208,30 @@ const formRules = reactive<any>({
//
const setFormData = async (data: Record<any, any>) => {
deptAll({ 'org_id': data.org_id }).then((res) => {
Object.assign(jobs, res)
})
if (data.annex.length > 0) {
if (data.annex.includes(",")) {
const arry1 = data.annex.split(',').map((item: any, index: any) => {
return {
name: `文件${index + 1}`,
uri: item
};
});
Object.assign(formDataannex, arry1)
} else {
const arry1 = [{ name: `文件1`, uri: data.annex }]
Object.assign(formDataannex, arry1)
}
}
// console.log(jobs)
project_name.value = data.project_name
custom_name.value = data.custom_name
project_code.value = data.project_code
customer_demand_name.value = data.customer_demand_name
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
@ -126,6 +252,9 @@ const getDetail = async (row: Record<string, any>) => {
//
const handleSubmit = async () => {
if (formDataannex.length > 0) {
formData.annex = formDataannex.map((item) => item.uri).toString()
}
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
@ -147,7 +276,7 @@ const handleClose = () => {
}
getlista()
defineExpose({
open,
setFormData,

View File

@ -21,38 +21,30 @@
</template>
新增
</el-button>
<el-button v-perms="['project.competitor/delete']" :disabled="!selectData.length"
@click="handleDelete(selectData)">
<el-button v-perms="['project.competitor/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="组织id" prop="org_id">
<template #default="{ row }">
<!-- <dict-value :options="dictData." :value="row.org_id" /> -->
</template>
</el-table-column>
<el-table-column label="部门id" prop="department_id">
<template #default="{ row }">
<!-- <dict-value :options="dictData." :value="row.department_id" /> -->
</template>
</el-table-column>
<el-table-column label="项目id" prop="project_id" show-overflow-tooltip />
<el-table-column label="项目名称" prop="project_name" show-overflow-tooltip />
<el-table-column label="客户名称" prop="custom_name" show-overflow-tooltip />
<el-table-column label="客户需求id" prop="customer_demand_id" show-overflow-tooltip />
<el-table-column label="竞争对手名称" prop="competitor_name" show-overflow-tooltip />
<el-table-column label="竞争对手联系人" prop="competitor_contacts" show-overflow-tooltip />
<el-table-column label="联系人电话" prop="competitor_contacts_phone" show-overflow-tooltip />
<el-table-column label="竞争能力" prop="competitive_power" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button v-perms="['project.competitor/edit']" type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button v-perms="['project.competitor/delete']" type="danger" link
@click="handleDelete(row.id)">
<el-button v-perms="['project.competitor/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['project.competitor/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -61,22 +53,26 @@
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
</div>
</template>
<script lang="ts" setup name="competitorLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiCompetitorLists, apiCompetitorDelete } from '@/api/competitor'
import { apiCompetitorLists, apiCompetitorDelete, apiCompetitorDetail } from '@/api/competitor'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -110,10 +106,11 @@ const handleAdd = async () => {
//
const handleEdit = async (data: any) => {
let res = await apiCompetitorDetail({ id: data.id })
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
editRef.value?.setFormData(res)
}
//
@ -122,7 +119,14 @@ const handleDelete = async (id: number | any[]) => {
await apiCompetitorDelete({ id })
getLists()
}
//
const handledetail = async (data: any) => {
let res = await apiCompetitorDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,194 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="项目合同详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="合同名称">
{{ formData.contract_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="合同编号">
{{ formData.contract_code }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="合同类型">
<dict-value :options="dictData.contract_type" :value="formData.contract_type" />
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="合同计价方式">
<dict-value :options="dictData.contract_pricing_method" :value="formData.contract_pricing_method" />
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="甲方">
{{ formData.party_a }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="甲方主要负责人">
{{ formData.party_a_diretor }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="甲方电话">
{{ formData.party_a_phone }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="甲方手机">
{{ formData.party_a_mobile }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="甲方邮箱">
{{ formData.party_a_email }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="合同名称">
{{ formData.contract_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="乙方">
{{ formData.party_b }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="乙方主要负责人">
{{ formData.party_b_diretor }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="乙方电话">
{{ formData.party_a_phone }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="乙方手机">
{{ formData.party_b_mobile }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="乙方邮箱">
{{ formData.party_b_email }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="金额">
{{ formData.amount }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="金额大写">
{{ formData.amount_daxie }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="业务负责人">
{{ formData.business_director }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="合同有效期">
{{ formData.expire }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="签约日期">
{{ formData.contract_date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="主要条款">
{{ formData.main_content }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注">
{{ formData.remark }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
Object.assign(formData, data)
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -1,127 +1,120 @@
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="550px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-form-item label="客户id" prop="customer_id">
<el-input v-model="formData.customer_id" clearable placeholder="请输入客户id" />
</el-form-item>
<popup ref="popupRef" :title="popupTitle" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="140px" :rules="formRules">
<el-row>
<el-col :span="8">
<el-form-item label="客户id" prop="customer_id" @click="showDialog = true">
<el-input v-model="custom_name_" clearable placeholder="请输入客户id" />
</el-form-item> </el-col><el-col :span="8">
<el-form-item label="购买标书id" prop="buy_bidding_document_id">
<el-input v-model="formData.buy_bidding_document_id" clearable placeholder="请输入购买标书id" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="合同名称" prop="contract_name">
<el-input v-model="formData.contract_name" clearable placeholder="请输入合同名称" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="合同编号" prop="contract_code">
<el-input v-model="formData.contract_code" clearable placeholder="请输入合同编号" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="合同类型" prop="contract_type">
<el-select class="flex-1" v-model="formData.contract_type" clearable placeholder="请选择合同类型">
<el-option
v-for="(item, index) in dictData.contract_type"
:key="index"
:label="item.name"
:value="parseInt(item.value)"
/>
<el-option v-for="(item, index) in dictData.contract_type" :key="index" :label="item.name" :value="parseInt(item.value)" />
</el-select>
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="合同计价方式" prop="contract_pricing_method">
<el-select class="flex-1" v-model="formData.contract_pricing_method" clearable placeholder="请选择合同计价方式">
<el-option
v-for="(item, index) in dictData.contract_pricing_method"
:key="index"
:label="item.name"
:value="parseInt(item.value)"
/>
<el-option v-for="(item, index) in dictData.contract_pricing_method" :key="index" :label="item.name" :value="parseInt(item.value)" />
</el-select>
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="甲方" prop="party_a">
<el-input v-model="formData.party_a" clearable placeholder="请输入甲方" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="甲方通讯地址" prop="party_a_contact_address">
<el-input v-model="formData.party_a_contact_address" clearable placeholder="请输入甲方通讯地址" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="甲方主要负责人" prop="party_a_diretor">
<el-input v-model="formData.party_a_diretor" clearable placeholder="请输入甲方主要负责人" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="甲方电话" prop="party_a_phone">
<el-input v-model="formData.party_a_phone" clearable placeholder="请输入甲方电话" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="甲方手机" prop="party_a_mobile">
<el-input v-model="formData.party_a_mobile" clearable placeholder="请输入甲方手机" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="甲方邮箱" prop="party_a_email">
<el-input v-model="formData.party_a_email" clearable placeholder="请输入甲方邮箱" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="乙方" prop="party_b">
<el-input v-model="formData.party_b" clearable placeholder="请输入乙方" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="乙方通讯地址" prop="party_b_contact_address">
<el-input v-model="formData.party_b_contact_address" clearable placeholder="请输入乙方通讯地址" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="乙方主要负责人" prop="party_b_diretor">
<el-input v-model="formData.party_b_diretor" clearable placeholder="请输入乙方主要负责人" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="乙方电话" prop="party_b_phone">
<el-input v-model="formData.party_b_phone" clearable placeholder="请输入乙方电话" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="乙方手机" prop="party_b_mobile">
<el-input v-model="formData.party_b_mobile" clearable placeholder="请输入乙方手机" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="乙方邮箱" prop="party_b_email">
<el-input v-model="formData.party_b_email" clearable placeholder="请输入乙方邮箱" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="金额" prop="amount">
<el-input v-model="formData.amount" clearable placeholder="请输入金额" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="金额大写" prop="amount_daxie">
<el-input v-model="formData.amount_daxie" clearable placeholder="请输入金额大写" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="业务负责人" prop="business_director">
<el-input v-model="formData.business_director" clearable placeholder="请输入业务负责人" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="合同状态" prop="contract_status">
<el-input v-model="formData.contract_status" clearable placeholder="请输入合同状态" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="合同有效期" prop="expire">
<el-date-picker
class="flex-1 !flex"
v-model="formData.expire"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择合同有效期">
<el-date-picker class="flex-1 !flex" v-model="formData.expire" clearable type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择合同有效期">
</el-date-picker>
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="签约日期" prop="contract_date">
<el-date-picker
class="flex-1 !flex"
v-model="formData.contract_date"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择签约日期">
<el-date-picker class="flex-1 !flex" v-model="formData.contract_date" clearable type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择签约日期">
</el-date-picker>
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="主要条款" prop="main_content">
<el-input v-model="formData.main_content" clearable placeholder="请输入主要条款" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" clearable placeholder="请输入备注" />
</el-form-item></el-col><el-col :span="24">
<el-form-item label="附件" prop="field127">
<el-upload accept=".pdf" class="upload-demo" :show-file-list="false" aria-hidden="true" :headers="{ Token: userStore.token }" :action="base_url + '/upload/file'" :on-success="handleAvatarSuccess_four" ref="upload">
<el-button type="primary">
上传
</el-button>
</el-upload>
<div>
<div v-for="(item, index) in formDataannex" style="margin-left: 5px;display: block;">
<a style="margin-left: 10px; color: #4a5dff; align-self: flex-start" :href="item.uri" target="_blank">{{ item.name }}</a>
<span style="cursor: pointer;margin-left: 5px;" @click="delFileFn(index)">x</span>
</div>
</div>
</el-form-item>
<el-form-item label="附件" prop="annex">
<el-input v-model="formData.annex" clearable placeholder="请输入附件" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</popup>
<el-dialog v-model="showDialog" title="选择客户" width="70%">
<customDialog @customEvent="customEvent"></customDialog>
</el-dialog>
</div>
</template>
@ -141,7 +134,37 @@ const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const formDataannex = reactive([])
import configs from "@/config"
const base_url = configs.baseUrl + configs.urlPrefix
import useUserStore from "@/stores/modules/user";
const showDialog = ref(false)
const custom_name = ref('')
const userStore = useUserStore();
//
const handleAvatarSuccess_four = (
response,
uploadFile
) => {
if (response.code == 0) {
ElMessage.error(response.msg);
return;
}
formDataannex.push(
{ uri: response.data.uri, name: response.data.name }
);
};
//
const delFileFn = (index: number) => {
formDataannex.splice(index, 1)
}
const customEvent = (e: any) => {
formData.customer_id = e.id;
custom_name.value = e.name;
showDialog.value = false;
};
//
const popupTitle = computed(() => {

View File

@ -1,23 +1,14 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form
class="mb-[-16px]"
:model="queryParams"
inline
>
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="合同名称" prop="contract_name">
<el-input class="w-[280px]" v-model="queryParams.contract_name" clearable placeholder="请输入合同名称" />
</el-form-item>
<el-form-item label="合同类型" prop="contract_type">
<el-select class="w-[280px]" v-model="queryParams.contract_type" clearable placeholder="请选择合同类型">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in dictData.contract_type"
:key="index"
:label="item.name"
:value="item.value"
/>
<el-option v-for="(item, index) in dictData.contract_type" :key="index" :label="item.name" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item>
@ -33,11 +24,7 @@
</template>
新增
</el-button>
<el-button
v-perms="['contract.contract/delete']"
:disabled="!selectData.length"
@click="handleDelete(selectData)"
>
<el-button v-perms="['contract.contract/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
@ -67,22 +54,15 @@
<el-table-column label="签约日期" prop="contract_date" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button
v-perms="['contract.contract/edit']"
type="primary"
link
@click="handleEdit(row)"
>
<el-button v-perms="['contract.contract/edit']" type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button
v-perms="['contract.contract/delete']"
type="danger"
link
@click="handleDelete(row.approve_id)"
>
<el-button v-perms="['contract.contract/delete']" type="danger" link @click="handleDelete(row.approve_id)">
删除
</el-button>
<el-button v-perms="['contract.contract/detail']" link @click="handleDetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -91,6 +71,7 @@
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
@ -98,15 +79,18 @@
<script lang="ts" setup name="contractLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiContractLists, apiContractDelete } from '@/api/contract'
import { apiContractLists, apiContractDelete, apiContractDetail } from '@/api/contract'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -152,7 +136,18 @@ const handleDelete = async (approve_id: number | any[]) => {
await apiContractDelete({ approve_id })
getLists()
}
//
const handleDetail = async (data: any) => {
let res = await apiContractDetail({
id: data.id
})
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,171 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="项目合同详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="合同名称">
{{ formData.contract_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="合同编号">
{{ formData.contract_code }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="合同类型">
<dict-value :options="dictData.contract_type" :value="formData.contract_type" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="洽商类别">
<dict-value :options="dictData.negotiation_type" :value="formData.negotiation_type" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="洽商金额">
{{ formData.negotiation_amount }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="洽商编号">
{{ formData.negotiation_no }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="成本金额(人工)">
{{ formData.labor_costs }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="成本金额(材料">
{{ formData.material_costs }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="洽商质保到期时间">
{{ formData.Warranty_expire_date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="利润率">
{{ formData.profit_rate }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="利润">
{{ formData.profit }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="具体说明">
{{ formData.negotiation_content }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="签证报价表">
{{ formData.negotiation_quotation }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="洽商依据">
{{ formData.negotiation_basis }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
Object.assign(formData, data)
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -1,11 +1,7 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form
class="mb-[-16px]"
:model="queryParams"
inline
>
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="合同id" prop="contract_id">
<el-input class="w-[280px]" v-model="queryParams.contract_id" clearable placeholder="请输入合同id" />
</el-form-item>
@ -25,11 +21,7 @@
</template>
新增
</el-button>
<el-button
v-perms="['contract.contract_negotiation/delete']"
:disabled="!selectData.length"
@click="handleDelete(selectData)"
>
<el-button v-perms="['contract.contract_negotiation/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
@ -57,22 +49,15 @@
<el-table-column label="利润率" prop="profit_rate" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button
v-perms="['contract.contract_negotiation/edit']"
type="primary"
link
@click="handleEdit(row)"
>
<el-button v-perms="['contract.contract_negotiation/edit']" type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button
v-perms="['contract.contract_negotiation/delete']"
type="danger"
link
@click="handleDelete(row.id)"
>
<el-button v-perms="['contract.contract_negotiation/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['contract.contract_negotiation/detail']" link @click="handleDetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -81,6 +66,7 @@
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
@ -88,15 +74,17 @@
<script lang="ts" setup name="contractNegotiationLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiContractNegotiationLists, apiContractNegotiationDelete } from '@/api/contract_negotiation'
import { apiContractNegotiationLists, apiContractNegotiationDelete, apiContractNegotiationDetail } from '@/api/contract_negotiation'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -142,6 +130,18 @@ const handleDelete = async (id: number | any[]) => {
await apiContractNegotiationDelete({ id })
getLists()
}
//
const handleDetail = async (data: any) => {
let res = await apiContractNegotiationDetail({
id: data.id
})
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

362
src/views/custom/detail.vue Normal file
View File

@ -0,0 +1,362 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="客户详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px">
<el-card class="mb-2">
<div class="tit">客户基本资料1</div>
<el-row>
<el-col :span="8">
<el-form-item label="客户姓名">
{{ formData.name }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="客户属性">
{{ formData.custom_type }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="上级公司">
{{ formData.parent_company }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="电话" prop="phone" :rules="[{ validator: checkPhone, trigger: 'blur' }]">
{{ formData.phone }}
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="信用度" prop="credit_rating">
{{ formData.credit_rating }}
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="省" prop="province" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
{{ formData.province }}
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="市" prop="city" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
{{ formData.city }}
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="区" prop="area" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
{{ formData.area }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="地址" prop="address">
{{ formData.address }}
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" prop="notes">
{{ formData.notes }}
</el-form-item>
</el-col>
</el-row>
</el-card>
<el-card class="mb-2">
<div class="tit">主要负责人</div>
<el-row>
<el-col :span="8">
<el-form-item label="姓名" prop="master_name">
{{ formData.master_name }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="职位" prop="master_position">
{{ formData.master_position }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="手机" prop="master_phone">
{{ formData.master_phone }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="邮箱" prop="master_email">
{{ formData.master_email }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="电话" prop="master_telephone">
{{ formData.master_telephone }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="备注" prop="master_notes">
{{ formData.master_notes }}
</el-form-item>
</el-col>
</el-row>
</el-card>
<el-card class="mb-2">
<div class="tit">其他联系人</div>
<el-row>
<template v-for="(item, index) in formData.other_contacts" :key="index">
<el-col :span="12">
<el-form-item label="姓名" prop="field120">
{{ item.name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="职务" prop="field121">
{{ item.position }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机" prop="field122">
{{ item.phone }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="邮箱">
{{ item.email }}
</el-form-item>
</el-col>
</template>
</el-row>
</el-card>
<el-card class="mb-2">
<div class="tit">开票信息</div>
<el-row>
<el-col :span="8">
<el-form-item label="开票公司" prop="company_name">
{{ formData.company_name }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="纳税人识别" prop="company_tin">
{{ formData.company_tin }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="开户地址" prop="bank_open_address">
{{ formData.bank_open_address }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="公司电话" prop="company_telephone">
{{ formData.company_telephone }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="开户银行" prop="bank_name">
{{ formData.bank_name }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="银行账号" prop="bank_account">
{{ formData.bank_account }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import {
apiCityList,
apiAreaList,
apiProvinceList,
} from "@/api/common";
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
id: '',
name: '',
custom_type: '',
parent_company: 5565665,
phone: '',
credit_rating: '',
province: '',
city: '',
street: '',
address: '',
notes: '',
master_name: '',
master_position: '',
master_phone: '',
master_email: '',
master_telephone: '',
master_notes: '',
company_name: '',
company_tin: '',
bank_open_address: '',
company_telephone: '',
bank_name: '',
bank_account: '',
status: '',
other_contacts: [],
area: ""
})
//
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
if (key == 'province') {
await getCityList()
}
if (key == 'city') {
await getAreaList()
}
}
}
formData.other_contacts = JSON.parse(formData.other_contacts)
console.log(formData, '2222222222')
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
// console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
//
function province_change(value: string) {
getCityList();
}
function city_change(value: string) {
getAreaList();
}
// function brigade_change(value: string) {
// formData.brigade = value
// }
const getProvinceList = async () => {
const data = await apiProvinceList({});
datas["provinceOptions"] = data;
};
const getCityList = async () => {
const data = await apiCityList({ province_code: formData.province });
datas["cityOptions"] = data;
};
const getAreaList = async () => {
const data = await apiAreaList({ city_code: formData.city });
datas["areaOptions"] = data;
};
//
function other() {
formData.other_contacts.push({
name: "",
position: "",
phone: "",
email: "",
});
}
//
function otherdelete() {
formData.other_contacts.pop({
name: "",
position: "",
phone: "",
email: "",
});
}
getProvinceList();
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -25,7 +25,7 @@
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="电话" prop="phone">
<el-form-item label="电话" prop="phone" :rules="[{ validator: checkPhone, trigger: 'blur' }]">
<el-input v-model="formData.phone" placeholder="请输入电话" clearable :style="{ width: '100%' }">
</el-input>
</el-form-item>
@ -90,13 +90,13 @@
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="手机" prop="master_phone">
<el-form-item label="手机" prop="master_phone" :rules="[{ validator: checkPhone, trigger: 'blur' }]">
<el-input v-model="formData.master_phone" placeholder="请输入手机" clearable :style="{ width: '100%' }">
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="邮箱" prop="master_email">
<el-form-item label="邮箱" prop="master_email" :rules="[{ validator: userEmail, trigger: 'blur' }]">
<el-input v-model="formData.master_email" placeholder="请输入邮箱" clearable :style="{ width: '100%' }">
</el-input>
</el-form-item>
@ -130,12 +130,12 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机" prop="field122">
<el-form-item label="手机" prop="field122" :rules="[{ validator: checkPhone, trigger: 'blur' }]">
<el-input :disabled="isDisabled" v-model="item.phone" placeholder="请输入手机" clearable :style="{ width: '100%' }"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="邮箱">
<el-form-item label="邮箱" :rules="[{ validator: userEmail, trigger: 'blur' }]">
<el-input :disabled="isDisabled" v-model="item.email" placeholder="请输入邮箱" clearable :style="{ width: '100%' }"></el-input>
</el-form-item>
</el-col>
@ -228,7 +228,33 @@ const datas = reactive({
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑客户表' : '新增客户表'
})
const checkPhone = (rule: any, value: any, callback: (arg0: Error) => any) => {
const phoneReg = /^1[3|4|5|7|8][0-9]{9}$/
// if (!value) {
// return callback(new Error(''))
// }
setTimeout(() => {
if (phoneReg.test(value)) {
callback()
} else {
callback(new Error('电话号码格式不正确'))
}
}, 100)
}
const userEmail = (rule: any, value: string, callback: (arg0: Error | undefined) => void) => {
const mailReg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/
// if (!value) {
// return callback(new Error(''))
// }
setTimeout(() => {
if (mailReg.test(value)) {
callback()
} else {
callback(new Error('请输入正确的邮箱格式'))
}
}, 100)
};
//
const formData = reactive({
id: '',

View File

@ -44,16 +44,28 @@
<dict-value :options="dictData.custom_type" :value="row.custom_type" />
</template>
</el-table-column>
<el-table-column label="省" prop="province_name" show-overflow-tooltip />
<el-table-column label="联系人" prop="custom_type">
<template #default="{ row }">
<div>
<text v-for="(item, i) in row.other_contacts" :key="i">{{ item.name }}</text>
</div>
</template>
</el-table-column>
<el-table-column label="省" prop="custom_type">
<template #default="{ row }">
{{ row.province.province_name }}
</template>
</el-table-column>
<!-- <el-table-column label="省" prop="province_name" show-overflow-tooltip /> -->
<el-table-column label="职务" prop="master_position" show-overflow-tooltip />
<el-table-column label="电话" prop="master_telephone" show-overflow-tooltip />
<el-table-column label="手机" prop="master_phone" show-overflow-tooltip />
<el-table-column label="备注" prop="master_notes" show-overflow-tooltip />
<el-table-column label="负责人" show-overflow-tooltip />
<el-table-column label="负责人" prop="master_name" show-overflow-tooltip />
<el-table-column label="创建时间" prop="create_time" show-overflow-tooltip />
<el-table-column label="最后跟进" show-overflow-tooltip />
<el-table-column label="下次回访日期" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="最后跟进" prop="last_follow_date" show-overflow-tooltip />
<el-table-column label="下次回访日期" prop="next_follow_date" show-overflow-tooltip />
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button v-perms="['custom.custom/edit']" type="primary" link @click="handleEdit(row)">
编辑
@ -61,6 +73,10 @@
<el-button v-perms="['custom.custom/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['custom.custom/detail']" link @click="handleDetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -73,7 +89,9 @@
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
<detail-popup v-if="showDtail" ref="detailRef" @close="showDtail = false" />
</div>
</template>
@ -84,11 +102,13 @@ import { apiCustomLists, apiCustomDelete, apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
import Statistics from '@/components/statistics/index.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
const list = reactive([
{
name: "全部客户",
@ -163,13 +183,22 @@ const handleAdd = async () => {
//
const handleEdit = async (data: any) => {
let res = await apiCustomDetail({ id: data.id })
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(res)
}
//
const handleDetail = async (data: any) => {
let res = await apiCustomDetail({ id: data.id })
showDtail.value = true
await nextTick()
console.log(detailRef)
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
//
const handleDelete = async (id: number | any[]) => {

View File

@ -0,0 +1,171 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="客户联系人详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="客户名称" prop="custom_name">
{{ formData.custom_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="姓名" prop="name">
{{ formData.name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="职位" prop="position">
{{ formData.position }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机" prop="phone">
{{ formData.phone }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="电话">
{{ formData.telephone }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="邮箱" prop="email">
{{ formData.email }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注" prop="notes">
{{ formData.notes }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
id: '',
name: '',
custom_type: '',
parent_company: 5565665,
phone: '',
credit_rating: '',
province: '',
city: '',
street: '',
address: '',
notes: '',
master_name: '',
master_position: '',
master_phone: '',
master_email: '',
master_telephone: '',
master_notes: '',
company_name: '',
company_tin: '',
bank_open_address: '',
company_telephone: '',
bank_name: '',
bank_account: '',
status: '',
other_contacts: [],
area: ""
})
//
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
console.log(formData, '2222222222')
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -5,8 +5,7 @@
<el-row>
<el-col :span="12">
<el-form-item label="客户名称" prop="custom_name">
<el-input v-model="formData.custom_name" clearable placeholder="请选择客户"
@click="showDialog = true" />
<el-input v-model="formData.custom_name" clearable placeholder="请选择客户" @click="showDialog = true" />
</el-form-item>
</el-col>
<el-col :span="12">
@ -20,16 +19,16 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机" prop="phone">
<el-form-item label="手机" prop="phone" :rules="[{ validator: checkPhone, trigger: 'blur' }]">
<el-input v-model="formData.phone" clearable placeholder="请输入手机" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="电话" prop="telephone">
<el-form-item label="电话" prop="telephone" :rules="[{ validator: checkPhone, trigger: 'blur' }]">
<el-input v-model="formData.telephone" clearable placeholder="请输入电话" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="12" :rules="[{ validator: userEmail, trigger: 'blur' }]">
<el-form-item label="邮箱" prop="email">
<el-input v-model="formData.email" clearable placeholder="请输入邮箱" />
</el-form-item>
@ -44,9 +43,7 @@
<material-picker v-model="formData.annex" type="file" />
</el-form-item> -->
<el-form-item label="附件" prop="field127">
<el-upload accept=".pdf" class="upload-demo" :show-file-list="false" aria-hidden="true"
:headers="{ Token: userStore.token }" :action="base_url + '/upload/file'"
:on-success="handleAvatarSuccess_four" ref="upload">
<el-upload accept=".pdf" class="upload-demo" :show-file-list="false" aria-hidden="true" :headers="{ Token: userStore.token }" :action="base_url + '/upload/file'" :on-success="handleAvatarSuccess_four" ref="upload">
<el-button type="primary">
上传
</el-button>
@ -54,8 +51,7 @@
<div>
<div v-for="(item, index) in formData.annex" style="margin-left: 5px;display: block;">
<a style="margin-left: 10px; color: #4a5dff; align-self: flex-start" :href="item.uri"
target="_blank">{{ item.name }}</a>
<a style="margin-left: 10px; color: #4a5dff; align-self: flex-start" :href="item.uri" target="_blank">{{ item.name }}</a>
<span style="cursor: pointer;margin-left: 5px;" @click="delFileFn(index)">x</span>
</div>
</div>
@ -180,7 +176,33 @@ const getDetail = async (row: Record<string, any>) => {
setFormData(data)
}
const checkPhone = (rule: any, value: any, callback: (arg0: Error) => any) => {
const phoneReg = /^1[3|4|5|7|8][0-9]{9}$/
// if (!value) {
// return callback(new Error(''))
// }
setTimeout(() => {
if (phoneReg.test(value)) {
callback()
} else {
callback(new Error('电话号码格式不正确'))
}
}, 100)
}
const userEmail = (rule: any, value: string, callback: (arg0: Error | undefined) => void) => {
const mailReg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/
if (!value) {
return callback(new Error('邮箱不能为空'))
}
setTimeout(() => {
if (mailReg.test(value)) {
callback()
} else {
callback(new Error('请输入正确的邮箱格式'))
}
}, 100)
};
//
const handleSubmit = async () => {
await formRef.value?.validate()

View File

@ -21,8 +21,7 @@
</template>
新增
</el-button>
<el-button v-perms="['custom.custom_contacts/delete']" :disabled="!selectData.length"
@click="handleDelete(selectData)">
<el-button v-perms="['custom.custom_contacts/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
@ -35,17 +34,18 @@
<el-table-column label="电话" prop="telephone" show-overflow-tooltip />
<el-table-column label="邮箱" prop="email" show-overflow-tooltip />
<el-table-column label="备注" prop="notes" show-overflow-tooltip />
<el-table-column label="状态" prop="status" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button v-perms="['custom.custom_contacts/edit']" type="primary" link
@click="handleEdit(row)">
<el-button v-perms="['custom.custom_contacts/edit']" type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button v-perms="['custom.custom_contacts/delete']" type="danger" link
@click="handleDelete(row.id)">
<el-button v-perms="['custom.custom_contacts/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['custom.custom_contacts/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -55,6 +55,7 @@
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
<detail-popup v-if="showDtail" ref="detailRef" @close="showDtail = false" />
</div>
</template>
@ -65,12 +66,13 @@ import { apiCustomContactsLists, apiCustomContactsDelete, apiCustomContactsDetai
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
custom_id: '',
@ -123,7 +125,15 @@ const handleDelete = async (id: number | any[]) => {
await apiCustomContactsDelete({ id })
getLists()
}
//
const handledetail = async (data: any) => {
let res = await apiCustomContactsDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,167 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="客户跟进记录详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="主题">
{{ formData.name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系人">
{{ formData.contacts }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="日期">
{{ formData.date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="类型">
<dict-value :options="dictData.follow_type" :value="row.types" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="执行人">
{{ formData.admin_id }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="行动描述" prop="email">
{{ formData.description }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="位置" prop="notes">
{{ formData.coordinate }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下次回访日期" prop="notes">
{{ formData.next_follow_date }}
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="下次回访日期" prop="notes">
<material-picker v-model="formData.annex" />
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
id: '',
name: '',
custom_id: '',
custom_name: '',
contacts: '',
date: '',
types: '',
admin_id: '',
description: '',
annex: '',
coordinate: '',
next_follow_date: '',
status: '',
})
//
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
console.log(formData, '2222222222')
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -18,7 +18,7 @@
<el-form-item label="类型" prop="types" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-select class="flex-1" v-model="formData.types" clearable placeholder="请选择类型">
<el-option v-for="(item, index) in dictData.types" :key="index" :label="item.name" :value="parseInt(item.value)" />
<el-option v-for="(item, index) in dictData.follow_type" :key="index" :label="item.name" :value="parseInt(item.value)" />
</el-select>
</el-form-item>
<el-form-item label="执行人" prop="admin_id">

View File

@ -42,7 +42,7 @@
</el-table-column>
<el-table-column label="类型" prop="types">
<template #default="{ row }">
<dict-value :options="dictData.types" :value="row.types" />
<dict-value :options="dictData.follow_type" :value="row.types" />
</template>
</el-table-column>
<el-table-column label="执行人" prop="admin_id" show-overflow-tooltip />
@ -68,6 +68,9 @@
<el-button v-perms="['custom_follow.custom_follow/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['custom_follow.custom_follow/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -77,6 +80,7 @@
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
</div>
</template>
@ -88,10 +92,13 @@ import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import Statistics from '@/components/statistics/index.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
const list = reactive([
{
name: "今日跟进",
@ -156,7 +163,7 @@ const handleSelectionChange = (val: any[]) => {
}
//
const { dictData } = useDictData('types')
const { dictData } = useDictData('follow_type')
//
const { pager, getLists, resetParams, resetPage } = usePaging({
@ -187,6 +194,14 @@ const handleDelete = async (id: number | any[]) => {
await apiCustomFollowDelete({ id })
getLists()
}
//
const handledetail = async (data: any) => {
let res = await apiCustomFollowDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,175 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="售后详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="项目名称">
{{ formData.name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户名称">
{{ formData.contacts }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系人">
{{ formData.contacts }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系电话">
{{ formData.phone }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="分类">
<dict-value :options="dictData.classification" :value="formData.classification" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="紧急程度">
<dict-value :options="dictData.urgency" :value="formData.urgency" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="接待人">
{{ formData.receiver }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="投诉主题" prop="notes">
{{ formData.name }}
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="问题描述" prop="notes">
{{ formData.name }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
id: '',
project_id: '',
custom_id: '',
approve_id: '',
contacts: '',
phone: '',
date: '',
classification: '',
urgency: '',
receiver: '',
processed_admin_id: '',
name: '',
description: '',
notes: '',
annex: [],
status: '',
})
//
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
console.log(formData, '2222222222')
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -4,21 +4,21 @@
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-row :gutter="10">
<el-col :span="12">
<el-form-item label="项目id" prop="project_id">
<el-input v-model="formData.project_id" clearable placeholder="请输入项目id" />
<el-form-item label="项目名称" prop="project_id" @click="showDialog = true">
<el-input v-model="project_name" readonly clearable placeholder="请输入项目名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户id" prop="custom_id">
<el-input v-model="formData.custom_id" clearable placeholder="请输入客户id" />
<el-form-item label="客户名称" prop="custom_id">
<el-input v-model="custom_name" readonly clearable placeholder="请输入客户名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<!-- <el-col :span="12">
<el-form-item label="审批id" prop="approve_id">
<el-input v-model="formData.approve_id" clearable placeholder="请输入审批id" />
</el-form-item>
</el-col>
</el-col> -->
<el-col :span="12">
<el-form-item label="联系人" prop="contacts">
@ -89,7 +89,7 @@
</el-upload>
<div>
<div v-for="(item, index) in formData.annex" style="margin-left: 5px;display: block;">
<div v-for="(item, index) in formDataannex" style="margin-left: 5px;display: block;">
<a style="margin-left: 10px; color: #4a5dff; align-self: flex-start" :href="item.uri" target="_blank">{{ item.name }}</a>
<span style="cursor: pointer;margin-left: 5px;" @click="delFileFn(index)">x</span>
</div>
@ -122,13 +122,23 @@ import useUserStore from "@/stores/modules/user";
import configs from "@/config"
import reviewprocess from '@/components/reviewprocess/index.vue'
import costDialog from '@/components/budget/index.vue'
import peojectDialog from '@/components/ptoject/index.vue'
import peojectDialog from '@/components/project/index.vue'
const base_url = configs.baseUrl + configs.urlPrefix
const userStore = useUserStore();
const list = reactive([])
const showDialog = ref(false)
const custom_name = ref('')
const project_name = ref('')
const formDataannex = reactive([])
const customEvent = (e: any) => {
console.log(e)
formData.custom_id = e.custom_id
custom_name.value = e.custom_name
formData.project_id = e.id
project_name.value = e.name
showDialog.value = false;
};
@ -141,14 +151,14 @@ const handleAvatarSuccess_four = (
ElMessage.error(response.msg);
return;
}
formData.annex.push(
formDataannex.push(
{ uri: response.data.uri, name: response.data.name }
);
};
//
const delFileFn = (index: number) => {
formData.annex.splice(index, 1)
formDataannex.splice(index, 1)
}
defineProps({
@ -197,6 +207,23 @@ const formRules = reactive<any>({
//
const setFormData = async (data: Record<any, any>) => {
custom_name.value = data.custom.name
project_name.value = data.project.name
if (data.annex && data.annex.length > 0) {
if (data.annex.includes(",")) {
const arry1 = data.annex.split(',').map((item: any, index: any) => {
return {
name: `文件${index + 1}`,
uri: item
};
});
Object.assign(formDataannex, arry1)
} else {
const arry1 = [{ name: `文件1`, uri: data.annex }]
Object.assign(formDataannex, arry1)
}
}
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
@ -218,6 +245,9 @@ const getDetail = async (row: Record<string, any>) => {
//
const handleSubmit = async () => {
if (formDataannex.length > 0) {
formData.annex = formDataannex.map((item) => item.uri).toString()
}
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'

View File

@ -12,8 +12,7 @@
<el-form-item label="紧急程度" prop="urgency">
<el-select class="w-[280px]" v-model="queryParams.urgency" clearable placeholder="请选择紧急程度">
<el-option label="全部" value=""></el-option>
<el-option v-for="(item, index) in dictData.urgency" :key="index" :label="item.name"
:value="item.value" />
<el-option v-for="(item, index) in dictData.urgency" :key="index" :label="item.name" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item>
@ -29,8 +28,7 @@
</template>
新增
</el-button>
<el-button v-perms="['custom_service.custom_service/delete']" :disabled="!selectData.length"
@click="handleDelete(selectData)">
<el-button v-perms="['custom_service.custom_service/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
@ -38,7 +36,6 @@
<el-table-column type="selection" width="55" />
<el-table-column label="项目" prop="project_id" show-overflow-tooltip />
<el-table-column label="客户" prop="custom_id" show-overflow-tooltip />
<el-table-column label="审批" prop="approve_id" show-overflow-tooltip />
<el-table-column label="联系人" prop="contacts" show-overflow-tooltip />
<el-table-column label="电话" prop="phone" show-overflow-tooltip />
<el-table-column label="日期" prop="date">
@ -62,16 +59,17 @@
<el-table-column label="问题描述" prop="description" show-overflow-tooltip />
<el-table-column label="备注" prop="notes" show-overflow-tooltip />
<el-table-column label="状态" prop="status" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button v-perms="['custom_service.custom_service/edit']" type="primary" link
@click="handleEdit(row)">
<el-button v-perms="['custom_service.custom_service/edit']" type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button v-perms="['custom_service.custom_service/delete']" type="danger" link
@click="handleDelete(row.id)">
<el-button v-perms="['custom_service.custom_service/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['custom_service.custom_service/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -81,6 +79,7 @@
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
</div>
</template>
@ -91,11 +90,14 @@ import { apiCustomServiceLists, apiCustomServiceDelete, apiCustomServiceDetail }
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -155,6 +157,15 @@ const handleDelete = async (id: number | any[]) => {
await apiCustomServiceDelete({ id })
getLists()
}
//
const handledetail = async (data: any) => {
let res = await apiCustomServiceDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,159 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="客户需求详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="组织">
{{ formData.org_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门">
{{ formData.dept_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目名称">
{{ formData.project_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户名称">
{{ formData.custom_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目编码">
{{ formData.project_code }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="需求主题">
{{ formData.theme }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="需求提供人">
{{ formData.supplier }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="提供人联系方式">
{{ formData.supplier_contacts }}
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="重要程度">
<dict-value :options="dictData.importance" :value="formData.importance" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="记录时间">
{{ formData.recording_time }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="需求内容">
{{ formData.demand_content }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
Object.assign(formData, data)
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -1,29 +1,27 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-form-item label="组织id" prop="org_id">
<el-select class="flex-1" v-model="formData.org_id" clearable placeholder="请选择组织id">
<!-- <el-option
v-for="(item, index) in dictData."
:key="index"
:label="item.name"
:value="parseInt(item.value)"
/> -->
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
<el-form-item label="组织id" prop="org_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-select class="flex-1" v-model="formData.org_id" clearable placeholder="请选择组织id" @change="area_change">
<el-option v-for="(item, index) in orglist" :key="index" :label="item.name" :value="parseInt(item.id)" />
</el-select>
</el-form-item>
<el-form-item label="部门id" prop="department_id">
<el-select class="flex-1" v-model="formData.department_id" clearable placeholder="请选择部门id">
<!-- <el-option
v-for="(item, index) in dictData."
:key="index"
:label="item.name"
:value="parseInt(item.value)"
/> -->
<el-form-item label="部门id" prop="dept_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-select class="flex-1" v-model="formData.dept_id" clearable placeholder="请选择部门id">
<el-option v-for="(item, index) in jobs" :key="index" :label="item.name" :value="parseInt(item.id)" />
</el-select>
</el-form-item>
<el-form-item label="项目id" prop="project_id">
<el-input v-model="formData.project_id" clearable placeholder="请输入项目id" />
<el-form-item label="项目名称" prop="project_id" @click="showDialog = true" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="project_name" clearable placeholder="请输入项目id" />
</el-form-item>
<el-form-item label="项目编码" prop="project_id">
<el-input v-model="project_code
" clearable placeholder="请输入项目id" />
</el-form-item>
<el-form-item label="客户名称" prop="project_id">
<el-input v-model="custom_name
" clearable placeholder="请输入项目id" />
</el-form-item>
<el-form-item label="需求主题" prop="theme">
<el-input v-model="formData.theme" clearable placeholder="请输入需求主题" />
@ -31,36 +29,52 @@
<el-form-item label="需求提供人" prop="supplier">
<el-input v-model="formData.supplier" clearable placeholder="请输入需求提供人" />
</el-form-item>
<el-form-item label="提供人联系方式" prop="supplier_contacts">
<el-form-item label="提供人联系方式" prop="supplier_contacts" :rules="[{ validator: checkPhone, trigger: 'blur' }]">
<el-input v-model="formData.supplier_contacts" clearable placeholder="请输入提供人联系方式" />
</el-form-item>
<el-form-item label="重要程度1非常重要2重要3一般4不重要" prop="importance">
<el-radio-group v-model="formData.importance" placeholder="请选择重要程度1非常重要2重要3一般4不重要">
<el-form-item label="重要程度" prop="importance">
<el-radio-group v-model="formData.importance" placeholder="请选择重要程度">
<el-radio v-for="(item, index) in dictData.importance" :key="index" :label="parseInt(item.value)">
{{ item.name }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="记录时间" prop="recording_time">
<el-date-picker class="flex-1 !flex" v-model="formData.recording_time" clearable type="datetime"
value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择记录时间">
<el-date-picker class="flex-1 !flex" v-model="formData.recording_time" clearable type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择记录时间">
</el-date-picker>
</el-form-item>
<el-form-item label="需求内容" prop="demand_content">
<el-input v-model="formData.demand_content" clearable placeholder="请输入需求内容" />
</el-form-item>
<el-form-item label="附件" prop="annex">
<el-input v-model="formData.annex" clearable placeholder="请输入附件" />
<el-form-item label="附件" prop="field127">
<el-upload accept=".pdf" class="upload-demo" :show-file-list="false" aria-hidden="true" :headers="{ Token: userStore.token }" :action="base_url + '/upload/file'" :on-success="handleAvatarSuccess_four" ref="upload">
<el-button type="primary">
上传
</el-button>
</el-upload>
<div>
<div v-for="(item, index) in formDataannex" style="margin-left: 5px;display: block;">
<a style="margin-left: 10px; color: #4a5dff; align-self: flex-start" :href="item.uri" target="_blank">{{ item.name }}</a>
<span style="cursor: pointer;margin-left: 5px;" @click="delFileFn(index)">x</span>
</div>
</div>
</el-form-item>
</el-form>
</popup>
<el-dialog v-model="showDialog" title="选择项目" width="70%">
<projectTable @customEvent="customEvent"></projectTable>
</el-dialog>
</div>
</template>
<script lang="ts" setup name="customerDemandEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { deptAll } from '@/api/org/department'
import { getAll } from '@/api/org/organization'
import projectTable from "@/components/project/index.vue"
import { apiCustomerDemandAdd, apiCustomerDemandEdit, apiCustomerDemandDetail } from '@/api/customer_demand'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
@ -74,8 +88,69 @@ const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const orglist = reactive([])
const jobs = reactive([])
const project_name
= ref('')
const project_code
= ref('')
const custom_name
= ref('')
const formDataannex = reactive([])
import configs from "@/config"
const base_url = configs.baseUrl + configs.urlPrefix
import useUserStore from "@/stores/modules/user";
const userStore = useUserStore();
//
const handleAvatarSuccess_four = (
response,
uploadFile
) => {
if (response.code == 0) {
ElMessage.error(response.msg);
return;
}
formDataannex.push(
{ uri: response.data.uri, name: response.data.name }
);
};
//
const delFileFn = (index: number) => {
formDataannex.splice(index, 1)
}
// dialog
const showDialog = ref(false)
const customEvent = (e: any) => {
formData.project_id = e.id;
project_name.value = e.name;
project_code
.value = e.project_code;
custom_name
.value = e.custom_name;
showDialog.value = false;
};
const getlista = () => {
getAll().then((res) => {
// orglist = res.data
Object.assign(orglist, res)
})
}
const area_change = (e: any) => {
formData.org_id = e
let data = { 'org_id': e }
// console.log(data)
deptAll(data).then((res) => {
Object.assign(jobs, res)
})
}
//
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑客户需求' : '新增客户需求'
@ -85,7 +160,7 @@ const popupTitle = computed(() => {
const formData = reactive({
id: '',
org_id: '',
department_id: '',
dept_id: '',
project_id: '',
theme: '',
supplier: '',
@ -95,7 +170,23 @@ const formData = reactive({
demand_content: '',
annex: '',
})
const checkPhone = (rule: any, value: any, callback: (arg0: Error) => any) => {
const phoneReg = /^1[3|4|5|7|8][0-9]{9}$/
// if (!value) {
// return callback(new Error(''))
// }
if (value) {
setTimeout(() => {
if (phoneReg.test(value)) {
callback()
} else {
callback(new Error('电话号码格式不正确'))
}
}, 100)
}
}
//
const formRules = reactive<any>({
@ -105,6 +196,27 @@ const formRules = reactive<any>({
//
const setFormData = async (data: Record<any, any>) => {
deptAll({ 'org_id': data.org_id }).then((res) => {
Object.assign(jobs, res)
})
if (data.annex.length > 0) {
if (data.annex.includes(",")) {
const arry1 = data.annex.split(',').map((item: any, index: any) => {
return {
name: `文件${index + 1}`,
uri: item
};
});
Object.assign(formDataannex, arry1)
} else {
const arry1 = [{ name: `文件1`, uri: data.annex }]
Object.assign(formDataannex, arry1)
}
}
project_name.value = data.project_name
custom_name.value = data.custom_name
project_code.value = data.project_code
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
@ -126,6 +238,9 @@ const getDetail = async (row: Record<string, any>) => {
//
const handleSubmit = async () => {
if (formDataannex.length > 0) {
formData.annex = formDataannex.map((item) => item.uri).toString()
}
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
@ -147,7 +262,7 @@ const handleClose = () => {
}
getlista()
defineExpose({
open,
setFormData,

View File

@ -20,28 +20,19 @@
</template>
新增
</el-button>
<el-button v-perms="['custom/demand.customer_demand/delete']" :disabled="!selectData.length"
@click="handleDelete(selectData)">
<el-button v-perms="['custom/demand.customer_demand/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="组织id" prop="org_id">
<template #default="{ row }">
<!-- <dict-value :options="dictData." :value="row.org_id" /> -->
</template>
</el-table-column>
<el-table-column label="部门id" prop="department_id">
<template #default="{ row }">
<!-- <dict-value :options="dictData." :value="row.department_id" /> -->
</template>
</el-table-column>
<el-table-column label="项目id" prop="project_id" show-overflow-tooltip />
<el-table-column label="项目名称" prop="project_name" show-overflow-tooltip />
<el-table-column label="客户名称" prop="custom_name" show-overflow-tooltip />
<el-table-column label="需求主题" prop="theme" show-overflow-tooltip />
<el-table-column label="需求提供人" prop="supplier" show-overflow-tooltip />
<el-table-column label="提供人联系方式" prop="supplier_contacts" show-overflow-tooltip />
<el-table-column label="重要程度1非常重要2重要3一般4不重要" prop="importance">
<el-table-column label="重要程度" prop="importance">
<template #default="{ row }">
<dict-value :options="dictData.importance" :value="row.importance" />
</template>
@ -53,17 +44,18 @@
</template>
</el-table-column>
<el-table-column label="需求内容" prop="demand_content" show-overflow-tooltip />
<el-table-column label="附件" prop="annex" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button v-perms="['custom/demand.customer_demand/edit']" type="primary" link
@click="handleEdit(row)">
<el-button v-perms="['custom/demand.customer_demand/edit']" type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button v-perms="['custom/demand.customer_demand/delete']" type="danger" link
@click="handleDelete(row.id)">
<el-button v-perms="['custom/demand.customer_demand/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['custom/demand.customer_demand/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -73,21 +65,26 @@
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
</div>
</template>
<script lang="ts" setup name="customerDemandLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiCustomerDemandLists, apiCustomerDemandDelete } from '@/api/customer_demand'
import { apiCustomerDemandLists, apiCustomerDemandDelete, apiCustomerDemandDetail } from '@/api/customer_demand'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -129,10 +126,11 @@ const handleAdd = async () => {
//
const handleEdit = async (data: any) => {
let res = await apiCustomerDemandDetail({ id: data.id })
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
editRef.value?.setFormData(res)
}
//
@ -141,6 +139,15 @@ const handleDelete = async (id: number | any[]) => {
await apiCustomerDemandDelete({ id })
getLists()
}
//
const handledetail = async (data: any) => {
let res = await apiCustomerDemandDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,156 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="客户需求详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="组织">
{{ formData.org_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门">
{{ formData.dept_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目名称">
{{ formData.project_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户名称">
{{ formData.custom_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目编码">
{{ formData.project_code }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="需求名称">
{{ formData.customer_demand_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="解决方案主题">
{{ formData.theme }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="方案内容">
{{ formData.solution_content }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户反馈">
{{ formData.customer_feedback }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="提交时间">
{{ formData.submission_time }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
Object.assign(formData, data)
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -1,33 +1,36 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-form-item label="组织id" prop="org_id">
<el-select class="flex-1" v-model="formData.org_id" clearable placeholder="请选择组织id">
<!-- <el-option
v-for="(item, index) in dictData."
:key="index"
:label="item.name"
:value="parseInt(item.value)"
/> -->
<popup ref="popupRef" :title="popupTitle" :async="true" width="650px" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
<el-form-item label="组织id" prop="org_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-select class="flex-1" v-model="formData.org_id" clearable placeholder="请选择组织id" @change="area_change">
<el-option v-for="(item, index) in orglist" :key="index" :label="item.name" :value="parseInt(item.id)" />
</el-select>
</el-form-item>
<el-form-item label="部门id" prop="department_id">
<el-input class="flex-1" v-model="formData.department_id" type="textarea" rows="4" clearable
placeholder="请输入部门id" />
<el-form-item label="部门id" prop="dept_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-select class="flex-1" v-model="formData.dept_id" clearable placeholder="请选择部门id">
<el-option v-for="(item, index) in jobs" :key="index" :label="item.name" :value="parseInt(item.id)" />
</el-select>
</el-form-item>
<el-form-item label="项目id" prop="project_id">
<el-input v-model="formData.project_id" clearable placeholder="请输入项目id" />
<el-form-item label="项目名称" prop="project_id" @click="showDialog = true" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="project_name" clearable placeholder="请输入项目名称" />
</el-form-item>
<el-form-item label="客户需求id" prop="customer_demand_id">
<el-input v-model="formData.customer_demand_id" clearable placeholder="请输入客户需求id" />
<el-form-item label="项目编码" prop="project_id">
<el-input v-model="project_code
" clearable placeholder="请输入项目编码" />
</el-form-item>
<el-form-item label="需求主题" prop="theme">
<el-input v-model="formData.theme" clearable placeholder="请输入需求主题" />
<el-form-item label="客户名称" prop="project_id">
<el-input v-model="custom_name
" clearable placeholder="请输入客户名称" />
</el-form-item>
<el-form-item label="需求名称" prop="customer_demand_id">
<el-input v-model="customer_demand_name" clearable placeholder="输入需求名称" @click="showDialog1 = true" />
</el-form-item>
<el-form-item label="解决方案主题" prop="theme">
<el-input v-model="formData.theme" clearable placeholder="请输入解决方案主题" />
</el-form-item>
<el-form-item label="提交时间" prop="submission_time">
<el-date-picker class="flex-1 !flex" v-model="formData.submission_time" clearable type="datetime"
value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择提交时间">
<el-date-picker class="flex-1 !flex" v-model="formData.submission_time" clearable type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择提交时间">
</el-date-picker>
</el-form-item>
@ -37,17 +40,40 @@
<el-form-item label="客户反馈" prop="customer_feedback">
<el-input v-model="formData.customer_feedback" clearable placeholder="请输入客户反馈" />
</el-form-item>
<el-form-item label="附件" prop="annex">
<el-input v-model="formData.annex" clearable placeholder="请输入附件" />
<el-form-item label="附件" prop="field127">
<el-upload accept=".pdf" class="upload-demo" :show-file-list="false" aria-hidden="true" :headers="{ Token: userStore.token }" :action="base_url + '/upload/file'" :on-success="handleAvatarSuccess_four" ref="upload">
<el-button type="primary">
上传
</el-button>
</el-upload>
<div>
<div v-for="(item, index) in formDataannex" style="margin-left: 5px;display: block;">
<a style="margin-left: 10px; color: #4a5dff; align-self: flex-start" :href="item.uri" target="_blank">{{ item.name }}</a>
<span style="cursor: pointer;margin-left: 5px;" @click="delFileFn(index)">x</span>
</div>
</div>
</el-form-item>
</el-form>
</popup>
<el-dialog v-model="showDialog" title="选择项目" width="70%">
<projectTable @customEvent="customEvent"></projectTable>
</el-dialog>
<el-dialog v-model="showDialog1" title="选择需求" width="70%">
<customerdemand @customEvent="customEvent1" :productid="formData.project_id"></customerdemand>
</el-dialog>
</div>
</template>
<script lang="ts" setup name="customerDemandSolutionEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { deptAll } from '@/api/org/department'
import { getAll } from '@/api/org/organization'
import projectTable from "@/components/project/index.vue"
import customerdemand from "@/components/customerdemand/index.vue"
import { apiCustomerDemandSolutionAdd, apiCustomerDemandSolutionEdit, apiCustomerDemandSolutionDetail } from '@/api/customer_demand_solution'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
@ -61,7 +87,74 @@ const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const orglist = reactive([])
const jobs = reactive([])
const project_name
= ref('')
const project_code
= ref('')
const custom_name
= ref('')
const customer_demand_name = ref('')
const formDataannex = reactive([])
import configs from "@/config"
const base_url = configs.baseUrl + configs.urlPrefix
import useUserStore from "@/stores/modules/user";
const userStore = useUserStore();
//
const handleAvatarSuccess_four = (
response,
uploadFile
) => {
if (response.code == 0) {
ElMessage.error(response.msg);
return;
}
formDataannex.push(
{ uri: response.data.uri, name: response.data.name }
);
};
//
const delFileFn = (index: number) => {
formDataannex.splice(index, 1)
}
// dialog
const showDialog = ref(false)
const showDialog1 = ref(false)
const customEvent = (e: any) => {
formData.project_id = e.id;
project_name.value = e.name;
project_code
.value = e.project_code;
custom_name
.value = e.custom_name;
showDialog.value = false;
};
const customEvent1 = (e: any) => {
formData.customer_demand_id = e.id;
customer_demand_name.value = e.theme;
showDialog1.value = false;
};
const getlista = () => {
getAll().then((res) => {
// orglist = res.data
Object.assign(orglist, res)
})
}
const area_change = (e: any) => {
formData.org_id = e
let data = { 'org_id': e }
// console.log(data)
deptAll(data).then((res) => {
Object.assign(jobs, res)
})
}
//
const popupTitle = computed(() => {
@ -72,7 +165,7 @@ const popupTitle = computed(() => {
const formData = reactive({
id: '',
org_id: '',
department_id: '',
dept_id: '',
project_id: '',
customer_demand_id: '',
theme: '',
@ -91,6 +184,29 @@ const formRules = reactive<any>({
//
const setFormData = async (data: Record<any, any>) => {
deptAll({ 'org_id': data.org_id }).then((res) => {
Object.assign(jobs, res)
})
if (data.annex.length > 0) {
if (data.annex.includes(",")) {
const arry1 = data.annex.split(',').map((item: any, index: any) => {
return {
name: `文件${index + 1}`,
uri: item
};
});
Object.assign(formDataannex, arry1)
} else {
const arry1 = [{ name: `文件1`, uri: data.annex }]
Object.assign(formDataannex, arry1)
}
}
console.log(jobs)
project_name.value = data.project_name
custom_name.value = data.custom_name
project_code.value = data.project_code
customer_demand_name.value = data.customer_demand_name
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
@ -112,6 +228,9 @@ const getDetail = async (row: Record<string, any>) => {
//
const handleSubmit = async () => {
if (formDataannex.length > 0) {
formData.annex = formDataannex.map((item) => item.uri).toString()
}
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
@ -132,7 +251,7 @@ const handleClose = () => {
emit('close')
}
getlista()
defineExpose({
open,

View File

@ -18,38 +18,37 @@
</template>
新增
</el-button>
<el-button v-perms="['custom.customer_demand_solution/delete']" :disabled="!selectData.length"
@click="handleDelete(selectData)">
<el-button v-perms="['custom.customer_demand_solution/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="组织id" prop="org_id">
<template #default="{ row }">
<!-- <dict-value :options="dictData." :value="row.org_id" /> -->
</template>
</el-table-column>
<el-table-column label="部门id" prop="department_id" show-overflow-tooltip />
<el-table-column label="项目id" prop="project_id" show-overflow-tooltip />
<el-table-column label="客户需求id" prop="customer_demand_id" show-overflow-tooltip />
<el-table-column label="需求主题" prop="theme" show-overflow-tooltip />
<el-table-column label="项目名称" prop="project_name" show-overflow-tooltip />
<el-table-column label="客户名称" prop="custom_name" show-overflow-tooltip />
<el-table-column label="需求名称" prop="customer_demand_name" show-overflow-tooltip />
<el-table-column label="解决方案主题" prop="theme" show-overflow-tooltip />
<el-table-column label="提交时间" prop="submission_time">
<template #default="{ row }">
<span>{{ row.submission_time ? timeFormat(row.submission_time, 'yyyy-mm-dd hh:MM:ss') : ''
}}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="方案内容" prop="solution_content" show-overflow-tooltip />
<el-table-column label="客户反馈" prop="customer_feedback" show-overflow-tooltip />
<el-table-column label="附件" prop="annex" show-overflow-tooltip />
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button v-perms="['custom.customer_demand_solution/edit']" type="primary" link
@click="handleEdit(row)">
<el-button v-perms="['custom.customer_demand_solution/edit']" type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button v-perms="['custom.customer_demand_solution/delete']" type="danger" link
@click="handleDelete(row.id)">
<el-button v-perms="['custom.customer_demand_solution/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['custom.customer_demand_solution/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -59,22 +58,24 @@
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
</div>
</template>
<script lang="ts" setup name="customerDemandSolutionLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiCustomerDemandSolutionLists, apiCustomerDemandSolutionDelete } from '@/api/customer_demand_solution'
import { apiCustomerDemandSolutionLists, apiCustomerDemandSolutionDelete, apiCustomerDemandSolutionDetail } from '@/api/customer_demand_solution'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
theme: ''
@ -106,10 +107,11 @@ const handleAdd = async () => {
//
const handleEdit = async (data: any) => {
let res = await apiCustomerDemandSolutionDetail({ id: data.id })
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
editRef.value?.setFormData(res)
}
//
@ -118,6 +120,15 @@ const handleDelete = async (id: number | any[]) => {
await apiCustomerDemandSolutionDelete({ id })
getLists()
}
//
const handledetail = async (data: any) => {
let res = await apiCustomerDemandSolutionDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -39,6 +39,7 @@ import type { FormInstance } from 'element-plus'
import { deptEdit, deptAdd, deptDetail, deptAll } from '@/api/org/department'
import { getAll } from '@/api/org/organization'
import Popup from '@/components/popup/index.vue'
import { useDictOptions } from '@/hooks/useDictOptions'
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()

View File

@ -0,0 +1,243 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="项目立项详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="160px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="项目名称">
{{ formData.name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户名称">
{{ formData.custom_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目类型">
<dict-value :options="dictData.project_type" :value="formData.project_type" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系人">
{{ formData.contacts }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系人职位">
{{ formData.position }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系电话">
{{ formData.telephone }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目所在地">
{{ formData.project_address }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="信息来源">
<dict-value :options="dictData.information_sources" :value="formData.information_sources" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="负责人">
{{ formData.person }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="战略意义">
<dict-value :options="dictData.strategic_significance" :value="formData.strategic_significance" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="招标方式" prop="notes">
<dict-value :options="dictData.bidding_method" :value="formData.bidding_method" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属行业" prop="notes">
<dict-value :options="dictData.industry" :value="formData.industry" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="单位性质" prop="notes">
<dict-value :options="dictData.unit_nature" :value="formData.unit_nature" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="竞争对手" prop="notes">
{{ formData.competitor }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目建设资金来源" prop="notes">
<dict-value :options="dictData.construction_funds_sources" :value="formData.construction_funds_sources" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="建设方付款方式" prop="notes">
{{ formData.construction_payment_method }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="建设方财务状况" prop="notes">
<dict-value :options="dictData.construction_financial_status" :value="formData.construction_financial_status" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="建设方对我方认可度" prop="notes">
<dict-value :options="dictData.construction_recognition" :value="formData.construction_recognition" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="我方对建设方认可度" prop="notes">
<dict-value :options="dictData.my_construction_recognition" :value="formData.my_construction_recognition" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="关系度" prop="notes">
<dict-value :options="dictData.relationship" :value="formData.relationship" />
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
id: '',
name: '',
custom_id: '',
custom_name: '',
project_type: '',
project_code: '',
project_content: [],
project_estimation: '',
project_address: '',
estimated_construction: '',
bidding_time: '',
bidding_method: '',
contacts: '',
position: '',
telephone: '',
department: '',
person: '',
relationship: '',
discovery_time: '',
information_sources: '',
competitor: '',
construction_funds_sources: '',
construction_payment_method: '',
construction_financial_status: '',
construction_recognition: '',
my_construction_recognition: '',
strategic_significance: '',
industry: '',
unit_nature: '',
annex: [],
status: '',
})
//
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
console.log(formData, '2222222222')
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: formData.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -11,10 +11,11 @@
<el-col :span="12">
<el-form-item label="项目类型" prop="project_type" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-select class="flex-1" v-model="formData.project_type" clearable placeholder="请选择项目类型">
<el-option v-for="(item, index) in dictData.project_type" :key="index" :label="item.name" :value="parseInt(item.value)" />
<el-option v-for="(item, index) in protype" :key="index" :label="item.name" :value="parseInt(item.id)" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目名称" prop="name" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.name" clearable placeholder="请输入项目名称" />
@ -219,11 +220,12 @@ import customDialog from '@/components/custom-dialog/index.vue'
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiProjectAdd, apiProjectEdit, apiProjectDetail } from '@/api/project'
import { getAllProjectTypes } from '@/api/projecttype'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
import configs from "@/config"
import useUserStore from "@/stores/modules/user";
const protype = reactive([])
const base_url = configs.baseUrl + configs.urlPrefix
const userStore = useUserStore();
//
@ -348,6 +350,11 @@ const handleSubmit = async () => {
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
getAllProjectTypes().then((res) => {
protype.splice(0, protype.length, ...res);
})
}
//

View File

@ -55,7 +55,7 @@
<el-form-item label="项目类型" prop="project_type">
<el-select class="w-[280px]" v-model="queryParams.project_type" clearable placeholder="请选择项目类型">
<el-option label="全部" value=""></el-option>
<el-option v-for="(item, index) in dictData.project_type" :key="index" :label="item.name" :value="item.value" />
<el-option v-for="(item, index) in protype" :key="index" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
@ -75,6 +75,7 @@
<el-button v-perms="['project.project/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
@ -83,7 +84,8 @@
<el-table-column label="项目名称" prop="name" show-overflow-tooltip />
<el-table-column label="项目类型" prop="project_type">
<template #default="{ row }">
<dict-value :options="dictData.project_type" :value="row.project_type" />
<!-- <dict-value :options="dictData.protype" :value="row.project_type" /> -->
{{ protype.find(item => item.id === row.project_type)?.name }}
</template>
</el-table-column>
@ -118,7 +120,7 @@
</template>
</el-table-column>
<el-table-column label="项目状态" prop="status" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button v-perms="['project.project/edit']" type="primary" link @click="handleEdit(row)">
编辑
@ -126,6 +128,9 @@
<el-button v-perms="['project.project/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['project.project/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -135,6 +140,7 @@
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
</div>
</template>
@ -143,13 +149,19 @@ import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiProjectLists, apiProjectDelete, apiProjectDetail } from '@/api/project'
import { timeFormat } from '@/utils/util'
import { getAllProjectTypes } from '@/api/projecttype'
const protype = reactive([])
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -209,6 +221,21 @@ const handleDelete = async (id: number | any[]) => {
await apiProjectDelete({ id })
getLists()
}
const handledetail = async (data: any) => {
let res = await apiProjectDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
//
const list = () => {
getAllProjectTypes().then((res) => {
protype.splice(0, protype.length, ...res);
})
}
list()
getLists()
</script>

View File

@ -0,0 +1,163 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="项目概算详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="组织">
{{ formData.org_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门">
{{ formData.dept_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目名称">
{{ formData.project_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户名称">
{{ formData.custom_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="需求名称">
{{ formData.customer_demand_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="概算来源">
<dict-value :options="dictData.estimate_source" :value="formData.estimate_source" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="制单人">
{{ formData.create_user }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="技术人员">
{{ formData.technician_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="报价日期">
{{ formData.quotation_date }}
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="发票类型">
<dict-value :options="dictData.invoice_type" :value="formData.invoice_type" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="概算金额">
{{ formData.estimate_amount }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="要求">
{{ formData.ask }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
Object.assign(formData, data)
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -2,36 +2,41 @@
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-form-item label="组织id" prop="org_id">
<el-select class="flex-1" v-model="formData.org_id" clearable placeholder="请选择组织id">
<!-- <el-option
v-for="(item, index) in dictData."
:key="index"
:label="item.name"
:value="parseInt(item.value)"
/> -->
<el-form-item label="组织" prop="org_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-select class="flex-1" readonly v-model="formData.org_id" clearable placeholder="请选择组织" @change="area_change">
<el-option v-for="(item, index) in orglist" :key="index" :label="item.name" :value="parseInt(item.id)" />
</el-select>
</el-form-item>
<el-form-item label="部门id" prop="department_id">
<el-select class="flex-1" v-model="formData.department_id" clearable placeholder="请选择部门id">
<!-- <el-option
v-for="(item, index) in dictData."
:key="index"
:label="item.name"
:value="parseInt(item.value)"
/> -->
<el-form-item label="部门" readonly prop="dept_id" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-select class="flex-1" v-model="formData.dept_id" clearable placeholder="请选择部门" @change="area_change1">
<el-option v-for="(item, index) in jobs" :key="index" :label="item.name" :value="parseInt(item.id)" />
</el-select>
</el-form-item>
<el-form-item label="项目id" prop="project_id">
<el-input v-model="formData.project_id" clearable placeholder="请输入项目id" />
<el-form-item label="项目名称" prop="project_id" @click="showDialog = true" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="project_name" readonly clearable placeholder="请输入项目名称" />
</el-form-item>
<el-form-item label="客户需求id" prop="customer_demand_id">
<el-input v-model="formData.customer_demand_id" clearable placeholder="请输入客户需求id" />
<el-form-item label="项目编码" prop="project_id">
<el-input v-model="project_code
" readonly clearable placeholder="请输入项目编码" />
</el-form-item>
<el-form-item label="客户名称" prop="project_id">
<el-input v-model="custom_name
" readonly clearable placeholder="请输入客户名称" />
</el-form-item>
<el-form-item label="需求名称" prop="customer_demand_id" @click="showDialog1 = true">
<el-input v-model="customer_demand_name" clearable readonly placeholder="请输入需求名称" />
</el-form-item>
<el-form-item label="联系人" prop="contact_id" @click="showDialog2 = true">
<el-input v-model="contact_name" clearable readonly placeholder="请输入联系人" />
</el-form-item>
<el-form-item label="联系电话" prop="customer_demand_id">
<el-input v-model="contact_phone" clearable readonly placeholder="请输入联系电话" />
</el-form-item>
<el-form-item label="概算来源" prop="estimate_source">
<el-radio-group v-model="formData.estimate_source" placeholder="请选择概算来源">
<el-radio v-for="(item, index) in dictData.estimate_source" :key="index"
:label="parseInt(item.value)">
<el-radio v-for="(item, index) in dictData.estimate_source" :key="index" :label="parseInt(item.value)">
{{ item.name }}
</el-radio>
</el-radio-group>
@ -40,8 +45,7 @@
<el-input v-model="formData.create_user" clearable placeholder="请输入制单人" />
</el-form-item>
<el-form-item label="报价日期" prop="quotation_date">
<el-date-picker class="flex-1 !flex" v-model="formData.quotation_date" clearable type="datetime"
value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择报价日期">
<el-date-picker class="flex-1 !flex" v-model="formData.quotation_date" clearable type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择报价日期">
</el-date-picker>
</el-form-item>
@ -53,7 +57,11 @@
</el-radio-group>
</el-form-item>
<el-form-item label="技术人员id" prop="technician">
<el-input v-model="formData.technician" clearable placeholder="请输入技术人员id" />
<el-select class="flex-1" v-model="formData.technician" clearable placeholder="请输入技术人员">
<el-option v-for="(item, index) in jlist" :key="index" :label="item.name" :value="parseInt(item.id)" />
</el-select>
<!-- <el-input v-model="formData.technician" clearable placeholder="请输入技术人员id" /> -->
</el-form-item>
<el-form-item label="概算金额" prop="estimate_amount">
<el-input v-model="formData.estimate_amount" clearable placeholder="请输入概算金额" />
@ -61,17 +69,42 @@
<el-form-item label="要求" prop="ask">
<el-input v-model="formData.ask" clearable placeholder="请输入要求" />
</el-form-item>
<el-form-item label="附件" prop="annex">
<el-input v-model="formData.annex" clearable placeholder="请输入附件" />
<el-form-item label="附件" prop="field127">
<el-upload accept=".pdf" class="upload-demo" :show-file-list="false" aria-hidden="true" :headers="{ Token: userStore.token }" :action="base_url + '/upload/file'" :on-success="handleAvatarSuccess_four" ref="upload">
<el-button type="primary">
上传
</el-button>
</el-upload>
<div>
<div v-for="(item, index) in formDataannex" style="margin-left: 5px;display: block;">
<a style="margin-left: 10px; color: #4a5dff; align-self: flex-start" :href="item.uri" target="_blank">{{ item.name }}</a>
<span style="cursor: pointer;margin-left: 5px;" @click="delFileFn(index)">x</span>
</div>
</div>
</el-form-item>
</el-form>
</popup>
<el-dialog v-model="showDialog" title="选择项目" width="70%">
<projectTable @customEvent="customEvent"></projectTable>
</el-dialog>
<el-dialog v-model="showDialog1" title="选择需求" width="70%">
<customerdemand @customEvent="customEvent1" :productid="formData.project_id"></customerdemand>
</el-dialog>
<el-dialog v-model="showDialog2" title="选择需求" width="70%">
<contactsTable @customEvent="customEvent2"></contactsTable>
</el-dialog>
</div>
</template>
<script lang="ts" setup name="projectEstimateEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { deptAll } from '@/api/org/department'
import { getAll } from '@/api/org/organization'
import projectTable from "@/components/project/index.vue"
import contactsTable from "@/components/contacts/index.vue"
import { getAdminsByDept } from '@/api/common'
import { apiProjectEstimateAdd, apiProjectEstimateEdit, apiProjectEstimateDetail } from '@/api/project_estimate'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
@ -85,7 +118,93 @@ const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const orglist = reactive([])
const jobs = reactive([])
const jlist = reactive([])
const project_name
= ref('')
const project_code
= ref('')
const custom_name
= ref('')
const customer_demand_name = ref('')
const contact_name = ref('')
const contact_phone = ref('')
const formDataannex = reactive([])
import configs from "@/config"
const base_url = configs.baseUrl + configs.urlPrefix
import useUserStore from "@/stores/modules/user";
const userStore = useUserStore();
//
const handleAvatarSuccess_four = (
response,
uploadFile
) => {
if (response.code == 0) {
ElMessage.error(response.msg);
return;
}
formDataannex.push(
{ uri: response.data.uri, name: response.data.name }
);
};
//
const delFileFn = (index: number) => {
formDataannex.splice(index, 1)
}
// dialog
const showDialog = ref(false)
const showDialog1 = ref(false)
const showDialog2 = ref(false)
const customEvent = (e: any) => {
formData.project_id = e.id;
project_name.value = e.name;
project_code
.value = e.project_code;
custom_name
.value = e.custom_name;
showDialog.value = false;
};
const customEvent1 = (e: any) => {
console.log(e.theme)
formData.customer_demand_id = e.id;
customer_demand_name.value = e.theme
showDialog1.value = false;
};
const customEvent2 = (e: any) => {
formData.contact_id = e.id;
contact_name.value = e.name;
contact_phone.value = e.phone
showDialog2.value = false;
};
const getlista = () => {
getAll().then((res) => {
// orglist = res.data
Object.assign(orglist, res)
})
}
const area_change = (e: any) => {
formData.org_id = e
let data = { 'org_id': e }
// console.log(data)
deptAll(data).then((res) => {
Object.assign(jobs, res)
})
}
const area_change1 = (e: any) => {
formData.dept_id = e
let data = { 'dept_id': e }
console.log(data)
getAdminsByDept(data).then((res) => {
Object.assign(jlist, res)
})
}
//
const popupTitle = computed(() => {
@ -96,7 +215,7 @@ const popupTitle = computed(() => {
const formData = reactive({
id: '',
org_id: '',
department_id: '',
dept_id: '',
project_id: '',
customer_demand_id: '',
estimate_source: '',
@ -107,6 +226,7 @@ const formData = reactive({
estimate_amount: '',
ask: '',
annex: '',
contact_id: ''
})
@ -118,6 +238,29 @@ const formRules = reactive<any>({
//
const setFormData = async (data: Record<any, any>) => {
deptAll({ 'org_id': data.org_id }).then((res) => {
Object.assign(jobs, res)
})
if (data.annex.length > 0) {
if (data.annex.includes(",")) {
const arry1 = data.annex.split(',').map((item: any, index: any) => {
return {
name: `文件${index + 1}`,
uri: item
};
});
Object.assign(formDataannex, arry1)
} else {
const arry1 = [{ name: `文件1`, uri: data.annex }]
Object.assign(formDataannex, arry1)
}
}
console.log(jobs)
project_name.value = data.project_name
custom_name.value = data.custom_name
project_code.value = data.project_code
customer_demand_name.value = data.customer_demand_name
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
@ -139,6 +282,9 @@ const getDetail = async (row: Record<string, any>) => {
//
const handleSubmit = async () => {
if (formDataannex.length > 0) {
formData.annex = formDataannex.map((item) => item.uri).toString()
}
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
@ -160,7 +306,7 @@ const handleClose = () => {
}
getlista()
defineExpose({
open,
setFormData,

View File

@ -18,25 +18,16 @@
</template>
新增
</el-button>
<el-button v-perms="['project.project_estimate/delete']" :disabled="!selectData.length"
@click="handleDelete(selectData)">
<el-button v-perms="['project.project_estimate/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="组织id" prop="org_id">
<template #default="{ row }">
<!-- <dict-value :options="dictData." :value="row.org_id" /> -->
</template>
</el-table-column>
<el-table-column label="部门id" prop="department_id">
<template #default="{ row }">
<!-- <dict-value :options="dictData." :value="row.department_id" /> -->
</template>
</el-table-column>
<el-table-column label="项目id" prop="project_id" show-overflow-tooltip />
<el-table-column label="客户需求id" prop="customer_demand_id" show-overflow-tooltip />
<el-table-column label="项目名称" prop="project_name" show-overflow-tooltip />
<el-table-column label="客户名称" prop="custom_name" show-overflow-tooltip />
<el-table-column label="需求" prop="customer_demand_name" show-overflow-tooltip />
<el-table-column label="概算来源" prop="estimate_source">
<template #default="{ row }">
<dict-value :options="dictData.estimate_source" :value="row.estimate_source" />
@ -54,18 +45,19 @@
<dict-value :options="dictData.invoice_type" :value="row.invoice_type" />
</template>
</el-table-column>
<el-table-column label="技术人员id" prop="technician" show-overflow-tooltip />
<el-table-column label="技术人员" prop="technician_name" show-overflow-tooltip />
<el-table-column label="概算金额" prop="estimate_amount" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button v-perms="['project.project_estimate/edit']" type="primary" link
@click="handleEdit(row)">
<el-button v-perms="['project.project_estimate/edit']" type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button v-perms="['project.project_estimate/delete']" type="danger" link
@click="handleDelete(row.id)">
<el-button v-perms="['project.project_estimate/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['project.project_estimate/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -75,21 +67,25 @@
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
</div>
</template>
<script lang="ts" setup name="projectEstimateLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiProjectEstimateLists, apiProjectEstimateDelete } from '@/api/project_estimate'
import { apiProjectEstimateLists, apiProjectEstimateDelete, apiProjectEstimateDetail } from '@/api/project_estimate'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -122,10 +118,11 @@ const handleAdd = async () => {
//
const handleEdit = async (data: any) => {
let res = await apiProjectEstimateDetail({ id: data.id })
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
editRef.value?.setFormData(res)
}
//
@ -135,6 +132,14 @@ const handleDelete = async (id: number | any[]) => {
getLists()
}
//
const handledetail = async (data: any) => {
let res = await apiProjectEstimateDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,187 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="项目更近记录详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="项目名称">
{{ formData.name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户名称">
{{ formData.custom_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目类型">
<dict-value :options="dictData.project_type" :value="formData.project_type" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="执行人">
{{ formData.project_code }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系人">
{{ formData.contacts }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系方式">
{{ formData.contact_information }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目角色">
{{ formData.project_role }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="职位">
{{ formData.position }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="跟进类型">
<dict-value :options="dictData.follow_type" :value="formData.follow_type" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="跟进日期">
{{ formData.follow_date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="主题">
{{ formData.theme }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="行动描述">
{{ formData.action_description }}
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="项目把握度">
<dict-value :options="dictData.project_assurance" :value="formData.project_assurance" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="跟进状态">
<dict-value :options="dictData.follow_status" :value="formData.follow_status" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="跟进阶段">
<dict-value :options="dictData.follow_stage" :value="formData.follow_stage" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注">
{{ formData.notes }}
</el-form-item>
</el-col> <el-col :span="12">
<el-form-item label="下次回访日期">
{{ formData.next_follow_up_date }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
Object.assign(formData, data)
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -1,81 +1,109 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit" @close="handleClose">
<popup ref="popupRef" :title="popupTitle" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
<el-row>
<el-col :span="8">
<el-form-item label="项目名称" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'change' }]">
<el-input v-model="project_name1" @click="showDialog = true" clearable placeholder="点击选择项目" />
<el-input v-model="project_name" readonly @click="showDialog = true" clearable placeholder="点击选择项目" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="项目编码" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'change' }]">
<el-input v-model="project_name2" @click="showDialog = true" clearable placeholder="点击选择项目" />
</el-form-item>
<el-input v-model="project_code" readonly @click="showDialog = true" clearable placeholder="点击选择项目" />
</el-form-item> </el-col><el-col :span="8">
<el-form-item label="客户名称" prop="project_id" :rules="[{ required: true, message: '不可为空', trigger: 'change' }]">
<el-input v-model="project_name3" @click="showDialog = true" clearable placeholder="点击选择项目" />
</el-form-item>
<el-input v-model="custom_name" readonly @click="showDialog = true" clearable placeholder="点击选择项目" />
</el-form-item> </el-col><el-col :span="8">
<el-form-item label="执行人" prop="executor">
<el-input v-model="formData.executor" clearable placeholder="请输入执行人" />
</el-form-item>
</el-form-item></el-col><el-col :span="8">
<el-form-item label="联系人" prop="contacts">
<el-input v-model="formData.contacts" clearable placeholder="请输入联系人" />
</el-form-item>
</el-form-item> </el-col><el-col :span="8">
<el-form-item label="联系方式" prop="contact_information">
<el-input v-model="formData.contact_information" clearable placeholder="请输入联系方式" />
</el-form-item>
<el-input v-model="formData.contact_information" clearable placeholder="请输入联系方式" @blur="validatephone()" />
</el-form-item> </el-col>
<el-col :span="8">
<el-form-item label="项目角色" prop="project_role">
<el-input v-model="formData.project_role" clearable placeholder="请输入项目角色" />
</el-form-item>
</el-form-item> </el-col><el-col :span="8">
<el-form-item label="职位" prop="position">
<el-input v-model="formData.position" clearable placeholder="请输入职位" />
</el-form-item>
</el-form-item> </el-col><el-col :span="8">
<el-form-item label="跟进日期" prop="follow_date" :rules="[{ required: true, message: '不可为空', trigger: 'change' }]">
<el-date-picker class="flex-1 !flex" v-model="formData.follow_date" clearable type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择跟进日期">
<el-date-picker class="flex-1 !flex" v-model="formData.follow_date" clearable type="date" value-format="YYYY-MM-DD" placeholder="选择跟进日期">
</el-date-picker>
</el-form-item>
</el-form-item> </el-col><el-col :span="8">
<el-form-item label="跟进类型" prop="follow_type" :rules="[{ required: true, message: '不可为空', trigger: 'change' }]">
<el-select class="flex-1" v-model="formData.follow_type" clearable placeholder="请选择跟进类型">
<el-option v-for="(item, index) in dictData.follow_type" :key="index" :label="item.name" :value="parseInt(item.value)" />
</el-select>
</el-form-item>
</el-form-item> </el-col><el-col :span="8">
<el-form-item label="主题" prop="theme" :rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.theme" clearable placeholder="请输入主题" />
</el-form-item>
</el-form-item> </el-col><el-col :span="8">
<el-form-item label="行动描述" prop="action_description">
<el-input v-model="formData.action_description" clearable placeholder="请输入行动描述" />
</el-form-item>
</el-form-item> </el-col><el-col :span="8">
<el-form-item label="项目把握度" prop="project_assurance" :rules="[{ required: true, message: '不可为空', trigger: 'change' }]">
<el-select class="flex-1" v-model="formData.project_assurance" clearable placeholder="请选择项目把握度">
<el-option v-for="(item, index) in dictData.project_assurance" :key="index" :label="item.name" :value="parseInt(item.value)" />
</el-select>
</el-form-item>
<el-form-item label="跟进状态" prop="follow_status">
</el-form-item> </el-col><el-col :span="8">
<el-form-item label="跟进状态" prop="follow_status" :rules="[{ required: true, message: '不可为空', trigger: 'change' }]">
<el-select class="flex-1" v-model="formData.follow_status" clearable placeholder="请选择跟进状态">
<el-option v-for="(item, index) in dictData.follow_status" :key="index" :label="item.name" :value="parseInt(item.value)" />
</el-select>
</el-form-item>
<el-form-item label="跟进阶段" prop="follow_stage">
</el-form-item> </el-col><el-col :span="8">
<el-form-item label="跟进阶段" prop="follow_stage" :rules="[{ required: true, message: '不可为空', trigger: 'change' }]">
<!-- <el-input v-model="formData.follow_stage" clearable placeholder="请输入跟进阶段" /> -->
<el-select class="flex-1" v-model="formData.follow_stage" clearable placeholder="请选择跟进状态">
<el-option v-for="(item, index) in dictData.follow_stage" :key="index" :label="item.name" :value="parseInt(item.value)" />
</el-select>
</el-form-item>
</el-form-item> </el-col><el-col :span="8">
<el-form-item label="备注" prop="notes">
<el-input v-model="formData.notes" clearable placeholder="请输入备注" />
</el-form-item>
</el-form-item> </el-col>
<el-col :span="8">
<el-form-item label="下次回访日期" prop="next_follow_up_date">
<el-date-picker class="flex-1 !flex" v-model="formData.next_follow_up_date" clearable type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择下次回访日期">
<el-date-picker v-model="formData.next_follow_up_date" clearable type="date" value-format="YYYY-MM-DD" placeholder="选择下次回访日期">
</el-date-picker>
</el-form-item>
<el-dialog v-model="showDialog" title="选择项目" width="70%">
<projectTable @customEvent="customEvent"></projectTable>
</el-dialog>
</el-col>
<el-col :span="24">
<el-form-item label="附件" prop="field127">
<el-upload accept=".pdf" class="upload-demo" :show-file-list="false" aria-hidden="true" :headers="{ Token: userStore.token }" :action="base_url + '/upload/file'" :on-success="handleAvatarSuccess_four" ref="upload">
<el-button type="primary">
上传
</el-button>
</el-upload>
<div>
<div v-for="(item, index) in formDataannex" style="margin-left: 5px;display: block;">
<a style="margin-left: 10px; color: #4a5dff; align-self: flex-start" :href="item.uri" target="_blank">{{ item.name }}</a>
<span style="cursor: pointer;margin-left: 5px;" @click="delFileFn(index)">x</span>
</div>
</div>
</el-form-item>
</el-col>
</el-row>
<!-- <el-form-item label="" prop="ceate_time">
<el-input v-model="formData.ceate_time" clearable placeholder="请输入" />
</el-form-item> -->
</el-form>
</popup>
<el-dialog v-model="showDialog" title="选择项目" width="70%">
<projectTable @customEvent="customEvent"></projectTable>
</el-dialog>
</div>
</template>
@ -96,17 +124,41 @@ const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const project_name1 = ref('')
const project_name2 = ref('')
const project_name3 = ref('')
const project_name = ref('')
const project_code = ref('')
const custom_name = ref('')
const formDataannex = reactive([])
import feedback from '@/utils/feedback'
import configs from "@/config"
const base_url = configs.baseUrl + configs.urlPrefix
import useUserStore from "@/stores/modules/user";
const userStore = useUserStore();
//
const handleAvatarSuccess_four = (
response,
uploadFile
) => {
if (response.code == 0) {
ElMessage.error(response.msg);
return;
}
formDataannex.push(
{ uri: response.data.uri, name: response.data.name }
);
};
//
const delFileFn = (index: number) => {
formDataannex.splice(index, 1)
}
// dialog
const showDialog = ref(false)
const customEvent = (e: any) => {
formData.project_id = e.id;
project_name1.value = e.name;
project_name2.value = e.project_code;
project_name3.value = e.custom_name;
project_name.value = e.name;
project_code.value = e.project_code;
custom_name
.value = e.custom_name;
showDialog.value = false;
};
@ -146,6 +198,26 @@ const formRules = reactive<any>({
//
const setFormData = async (data: Record<any, any>) => {
custom_name.value = data.custom_name
project_name.value = data.project_name
project_code.value = data.project_code
if (data.file.length > 0) {
if (data.file.includes(",")) {
const arry1 = data.file.split(',').map((item: any, index: any) => {
return {
name: `文件${index + 1}`,
uri: item
};
});
Object.assign(formDataannex, arry1)
} else {
const arry1 = [{ name: `文件1`, uri: data.file }]
Object.assign(formDataannex, arry1)
}
}
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
@ -154,9 +226,9 @@ const setFormData = async (data: Record<any, any>) => {
}
//@ts-ignore
formData.follow_date = timeFormat(formData.follow_date, 'yyyy-mm-dd hh:MM:ss')
// formData.follow_date = timeFormat(formData.follow_date, 'yyyy-mm-dd hh:MM:ss')
//@ts-ignore
formData.next_follow_up_date = timeFormat(formData.next_follow_up_date, 'yyyy-mm-dd hh:MM:ss')
// formData.next_follow_up_date = timeFormat(formData.next_follow_up_date, 'yyyy-mm-dd hh:MM:ss')
}
const getDetail = async (row: Record<string, any>) => {
@ -166,10 +238,22 @@ const getDetail = async (row: Record<string, any>) => {
setFormData(data)
}
const validatephone = (e: any) => {
const phoneReg = /^1[3|4|5|7|8][0-9]{9}$/
if (phoneReg.test(formData.contact_information)) {
} else {
feedback.msgError('电话号码格式不正确')
}
}
//
const handleSubmit = async () => {
if (formDataannex.length > 0) {
formData.file = formDataannex.map((item) => item.uri).toString()
}
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
? await apiProjectFollowUpEdit(data)

View File

@ -120,50 +120,47 @@
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="项目名称" prop="project_id" show-overflow-tooltip />
<el-table-column label="项目名称" prop="project_name" show-overflow-tooltip />
<el-table-column label="客户名称" prop="executor" show-overflow-tooltip />
<el-table-column label="执行人" prop="executor" show-overflow-tooltip />
<el-table-column label="联系人" prop="contacts" show-overflow-tooltip />
<el-table-column label="联系方式" prop="contact_information" show-overflow-tooltip />
<el-table-column label="项目角色" prop="project_role" show-overflow-tooltip />
<el-table-column label="职位" prop="position" show-overflow-tooltip />
<el-table-column label="跟进日期" prop="follow_date">
<el-table-column label="日期" prop="follow_date">
<template #default="{ row }">
<span>{{ row.follow_date ? timeFormat(row.follow_date, 'yyyy-mm-dd hh:MM:ss') : '' }}</span>
<span>{{ row.follow_date ? row.follow_date : '' }}</span>
</template>
</el-table-column>
<el-table-column label="跟进类型" prop="follow_type">
<el-table-column label="类型" prop="follow_type">
<template #default="{ row }">
<dict-value :options="dictData.follow_type" :value="row.follow_type" />
</template>
</el-table-column>
<el-table-column label="主题" prop="theme" show-overflow-tooltip />
<el-table-column label="行动描述" prop="action_description" show-overflow-tooltip />
<el-table-column label="项目把握度" prop="project_assurance">
<template #default="{ row }">
<dict-value :options="dictData.project_assurance" :value="row.project_assurance" />
</template>
<el-table-column label="项目把握度" prop="project_assurance_text">
</el-table-column>
<el-table-column label="跟进状态" prop="follow_status">
<el-table-column label="状态" prop="follow_status">
<template #default="{ row }">
<dict-value :options="dictData.follow_status" :value="row.follow_status" />
</template>
</el-table-column>
<el-table-column label="跟进阶段" prop="follow_stage">
<el-table-column label="阶段" prop="follow_stage">
<template #default="{ row }">
<dict-value :options="dictData.follow_stage" :value="row.follow_stage" />
</template>
</el-table-column>
<el-table-column label="备注" prop="notes" show-overflow-tooltip />
<!-- <el-table-column label="备注" prop="notes" show-overflow-tooltip /> -->
<el-table-column label="下次回访日期" prop="next_follow_up_date">
<template #default="{ row }">
<span>{{ row.next_follow_up_date ? timeFormat(row.next_follow_up_date, 'yyyy-mm-dd hh:MM:ss') :
<span>{{ row.next_follow_up_date ? row.next_follow_up_date :
'' }}</span>
</template>
</el-table-column>
<el-table-column label="" prop="ceate_time" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button v-perms="['project.project_follow_up/edit']" type="primary" link @click="handleEdit(row)">
编辑
@ -171,6 +168,9 @@
<el-button v-perms="['project.project_follow_up/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['project.project_follow_up/detail']" link @click="handledetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -180,21 +180,25 @@
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
</div>
</template>
<script lang="ts" setup name="projectFollowUpLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiProjectFollowUpLists, apiProjectFollowUpDelete } from '@/api/project_follow_up'
import { apiProjectFollowUpLists, apiProjectFollowUpDelete, apiProjectFollowUpDetail } from '@/api/project_follow_up'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -242,10 +246,11 @@ const handleAdd = async () => {
//
const handleEdit = async (data: any) => {
let res = await apiProjectFollowUpDetail({ id: data.id })
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
editRef.value?.setFormData(res)
}
//
@ -254,7 +259,14 @@ const handleDelete = async (id: number | any[]) => {
await apiProjectFollowUpDelete({ id })
getLists()
}
//
const handledetail = async (data: any) => {
let res = await apiProjectFollowUpDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,128 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="售前成员详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="项目名称">
{{ formData.project_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="技术人员">
{{ formData.technician }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="商务人员">
{{ formData.business_people }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="跨部门人员">
{{ formData.cross_departmental_personnel }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="添加人">
{{ formData.add_people }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
Object.assign(formData, data)
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -42,7 +42,7 @@
</div>
</el-form-item>
<el-dialog v-model="showDialog" title="选择客户" width="70%">
<el-dialog v-model="showDialog" title="选择项目" width="70%">
<projectTable @customEvent="customEvent"></projectTable>
</el-dialog>
@ -160,7 +160,8 @@
<script lang="ts" setup name="projectPreSalesMembersEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import projectTable from "@/components/tablieDialog/project.vue"
import projectTable from "@/components/project/index.vue"
import { computed, nextTick, onMounted, reactive, shallowRef, watch } from 'vue'
import { apiProjectPreSalesMembersAdd, apiProjectPreSalesMembersEdit, apiProjectPreSalesMembersDetail } from '@/api/project_pre_sales_members'
import { getAdminsByAll, getAllDept, getAllJobs, getAdminsByDept, getAdminsByJob } from '@/api/common'
import { timeFormat } from '@/utils/util'
@ -195,7 +196,8 @@ const technician
= ref([])
const business_people
= ref([])
// dialog
const showDialog = ref(false)
const customEvent = (e: any) => {
formData.project_id = e.id;
@ -205,7 +207,7 @@ const customEvent = (e: any) => {
//
const getlist = () => {
getAdminsByAll().then((res) => {
console.log(res)
// console.log(res)
Object.assign(uesrlist, res)
})
}
@ -254,6 +256,18 @@ const gwclck = (item: { id: any }) => {
//
const userone = (e: any) => {
leixin.value = e
if (mode.value != 'add') {
if (e == 1) {
const arry4 = [...technician.value]
radiolist.value = arry4
} else if (e == 2) {
const arry4 = [...business_people.value]
radiolist.value = arry4
} else {
const arry4 = [...cross_departmental_personnel.value]
radiolist.value = arry4
}
}
dialogVisible.value = true
}
//
@ -323,13 +337,67 @@ const formData = reactive({
const formRules = reactive<any>({
})
onMounted(() => {
getlist()
deparmet()
Jobs()
})
//
const setFormData = async (data: Record<any, any>) => {
technician.value = data.technician
business_people.value = data.business_people
cross_departmental_personnel.value = data.cross_departmental_personnel
getlist()
deparmet()
Jobs()
setTimeout(() => {
if (data.technician_ids && data.technician_ids.length > 0) {
if (data.technician_ids.includes(",")) {
const arry1 = data.technician_ids.split(',')
const arry2 = uesrlist
const arry3 = arry2.filter(obj => arry1.includes(obj.id.toString()))
technician.value = arry3
} else {
const arry1 = [data.technician_ids]
const arry2 = uesrlist
const arry3 = arry2.filter(obj => arry1.includes(obj.id.toString()))
technician.value = arry3
}
}
if (data.business_people_ids && data.business_people_ids.length > 0) {
if (data.business_people_ids.includes(",")) {
const arry1 = data.business_people_ids.split(',')
const arry2 = uesrlist
const arry3 = arry2.filter(obj => arry1.includes(obj.id.toString()))
business_people.value = arry3
} else {
const arry1 = [data.business_people_ids]
const arry2 = uesrlist
const arry3 = arry2.filter(obj => arry1.includes(obj.id.toString()))
business_people.value = arry3
}
}
if (data.cross_departmental_personnel_ids && data.cross_departmental_personnel_ids.length > 0) {
if (data.cross_departmental_personnel_ids.includes(",")) {
const arry1 = data.cross_departmental_personnel_ids.split(',')
const arry2 = uesrlist
const arry3 = arry2.filter(obj => arry1.includes(obj.id.toString()))
cross_departmental_personnel.value = arry3
} else {
const arry1 = [data.cross_departmental_personnel_ids]
const arry2 = uesrlist
const arry3 = arry2.filter(obj => arry1.includes(obj.id.toString()))
cross_departmental_personnel.value = arry3
}
}
// const arry4 = [...cross_departmental_personnel.value, ...business_people.value, ...technician.value]
// radiolist.value = arry4
},
1000)
// technician.value = data.technician
// business_people.value = data.business_people
// cross_departmental_personnel.value = data.cross_departmental_personnel
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
@ -371,9 +439,7 @@ const handleClose = () => {
}
getlist()
deparmet()
Jobs()
defineExpose({
open,
setFormData,

View File

@ -38,7 +38,7 @@
<el-table-column label="商务人员" prop="business_people" show-overflow-tooltip />
<el-table-column label="跨部门人员" prop="cross_departmental_personnel" show-overflow-tooltip />
<el-table-column label="添加人" prop="add_people" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button v-perms="['project.project_pre_sales_members/edit']" type="primary" link @click="handleEdit(row)">
编辑
@ -46,6 +46,9 @@
<el-button v-perms="['project.project_pre_sales_members/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['project.project_pre_sales_members/detail']" link @click="handleDetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -55,6 +58,7 @@
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
</div>
</template>
@ -65,11 +69,14 @@ import { apiProjectPreSalesMembersLists, apiProjectPreSalesMembersDelete, apiPro
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -120,7 +127,17 @@ const handleDelete = async (id: number | any[]) => {
await apiProjectPreSalesMembersDelete({ id })
getLists()
}
//
const handleDetail = async (data: any) => {
let res = await apiProjectPreSalesMembersDetail({
id: data.id
})
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,174 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="报价单详情" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px">
<el-card class="mb-2">
<el-row>
<el-col :span="12">
<el-form-item label="客户名称">
{{ formData.customer_name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="报价日期">
{{ formData.quotation_date }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系人">
{{ formData.contacts }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系电话">
{{ formData.contacts_phone }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="制单人">
{{ formData.create_user }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系人电话">
{{ formData.competitor_contacts_phone }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="发票类型">
<dict-value :options="dictData.invoice_type" :value="formData.invoice_type" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="含税金额">
{{ formData.amount_including_tax }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="运费">
{{ formData.freight }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="其他费用">
{{ formData.other_fee }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="合计金额">
{{ formData.total_amount }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户需求">
{{ formData.customer_require }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="运费">
{{ formData.freight }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注">
{{ formData.remark }}
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiCustomDetail } from '@/api/custom'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const datas = reactive({
provinceOptions: [],
cityOptions: [],
areaOptions: [],
});
//
const formData = reactive({
})
//
const setFormData = async (data: Record<any, any>) => {
Object.assign(formData, data)
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
// console.log('1111111')
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style lang="scss">
.tit {
font-size: 1.2em;
margin-bottom: 10px;
}
</style>

View File

@ -44,7 +44,7 @@
<el-table-column label="运费" prop="freight" show-overflow-tooltip />
<el-table-column label="其他费用" prop="other_fee" show-overflow-tooltip />
<el-table-column label="合计金额" prop="total_amount" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button v-perms="['quotation.quotation/edit']" type="primary" link @click="handleEdit(row)">
编辑
@ -52,6 +52,9 @@
<el-button v-perms="['quotation.quotation/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['quotation.quotation/detail']" link @click="handleDetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
@ -60,6 +63,7 @@
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<detail-popup v-if="showDtail" ref="detailRef" :dict-data="dictData" @close="showDtail = false" />
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
@ -71,11 +75,15 @@ import { apiQuotationLists, apiQuotationDelete, apiQuotationDetail } from '@/api
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
const detailRef = shallowRef<InstanceType<typeof DetailPopup>>()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDtail = ref(false)
//
const queryParams = reactive({
@ -128,7 +136,15 @@ const handleDelete = async (id: number | any[]) => {
await apiQuotationDelete({ id })
getLists()
}
//
const handleDetail = async (data: any) => {
let res = await apiQuotationDetail({ id: data.id })
showDtail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>