This commit is contained in:
zmj 2024-04-02 17:08:43 +08:00
parent d636dce1a7
commit 29c8a25a79
33 changed files with 2568 additions and 294 deletions

View File

@ -0,0 +1,37 @@
import request from '@/utils/request'
// 市场经营--客户信息列表
export function apiMarketingCustomLists(params: any) {
return request.get({ url: '/marketing.marketing_custom/lists', params })
}
// 添加市场经营--客户信息
export function apiMarketingCustomAdd(params: any) {
return request.post({ url: '/marketing.marketing_custom/add', params })
}
// 编辑市场经营--客户信息
export function apiMarketingCustomEdit(params: any) {
return request.post({ url: '/marketing.marketing_custom/edit', params })
}
// 删除市场经营--客户信息
export function apiMarketingCustomDelete(params: any) {
return request.post({ url: '/marketing.marketing_custom/delete', params })
}
// 市场经营--客户信息详情
export function apiMarketingCustomDetail(params: any) {
return request.get({ url: '/marketing.marketing_custom/detail', params })
}
// 删除市场经营--客户联系人
export function apiMarketingCustomContactsDelete(params: any) {
return request.post({ url: '/marketing.marketing_custom_contacts/delete', params })
}
// 市场经营--客户联系人列表
export function apiMarketingCustomContactsLists(params: any) {
return request.get({ url: '/marketing.marketing_custom_contacts/lists', params })
}

View File

@ -0,0 +1,45 @@
import request from '@/utils/request'
// 市场经营--客户回访列表列表
export function apiMarketingCustomReturnVisitLists(params: any) {
return request.get({ url: '/marketing.marketing_custom_return_visit/lists', params })
}
// 添加市场经营--客户回访列表
export function apiMarketingCustomReturnVisitAdd(params: any) {
return request.post({ url: '/marketing.marketing_custom_return_visit/add', params })
}
// 编辑市场经营--客户回访列表
export function apiMarketingCustomReturnVisitEdit(params: any) {
return request.post({ url: '/marketing.marketing_custom_return_visit/edit', params })
}
// 删除市场经营--客户回访列表
export function apiMarketingCustomReturnVisitDelete(params: any) {
return request.post({ url: '/marketing.marketing_custom_return_visit/delete', params })
}
// 市场经营--客户回访列表详情
export function apiMarketingCustomReturnVisitDetail(params: any) {
return request.get({ url: '/marketing.marketing_custom_return_visit/detail', params })
}
export function apimarketing_custom_return_visit_surveyLists(params: any) {
return request.get({ url: '/marketing.marketing_custom_return_visit_survey/lists', params })
}
// 删除市场经营--客户回访列表
export function apimarketing_custom_return_visit_surveytDelete(params: any) {
return request.post({ url: '/marketing.marketing_custom_return_visit_survey/delete', params })
}
export function apimarketing_custom_return_visit_evaluateLists(params: any) {
return request.get({ url: '/marketing.marketing_custom_return_visit_evaluate/lists', params })
}
// 删除市场经营--客户回访列表
export function apimarketing_custom_return_visit_evaluateDelete(params: any) {
return request.post({ url: '/marketing.marketing_custom_return_visit_evaluate/delete', params })
}

View File

@ -0,0 +1,26 @@
import request from '@/utils/request'
// 市场经营--客户回访列表--成员评价列表
export function apiMarketingCustomReturnVisitEvaluateLists(params: any) {
return request.get({ url: '/marketing.marketing_custom_return_visit_evaluate/lists', params })
}
// 添加市场经营--客户回访列表--成员评价
export function apiMarketingCustomReturnVisitEvaluateAdd(params: any) {
return request.post({ url: '/marketing.marketing_custom_return_visit_evaluate/add', params })
}
// 编辑市场经营--客户回访列表--成员评价
export function apiMarketingCustomReturnVisitEvaluateEdit(params: any) {
return request.post({ url: '/marketing.marketing_custom_return_visit_evaluate/edit', params })
}
// 删除市场经营--客户回访列表--成员评价
export function apiMarketingCustomReturnVisitEvaluateDelete(params: any) {
return request.post({ url: '/marketing.marketing_custom_return_visit_evaluate/delete', params })
}
// 市场经营--客户回访列表--成员评价详情
export function apiMarketingCustomReturnVisitEvaluateDetail(params: any) {
return request.get({ url: '/marketing.marketing_custom_return_visit_evaluate/detail', params })
}

View File

@ -0,0 +1,45 @@
import request from '@/utils/request'
// 市场经营--客户回访模板列表
export function apiMarketingCustomReturnVisitTemplateLists(params: any) {
return request.get({ url: '/marketing.marketing_custom_return_visit_template/lists', params })
}
// 添加市场经营--客户回访模板
export function apiMarketingCustomReturnVisitTemplateAdd(params: any) {
return request.post({ url: '/marketing.marketing_custom_return_visit_template/add', params })
}
// 编辑市场经营--客户回访模板
export function apiMarketingCustomReturnVisitTemplateEdit(params: any) {
return request.post({ url: '/marketing.marketing_custom_return_visit_template/edit', params })
}
// 删除市场经营--客户回访模板
export function apiMarketingCustomReturnVisitTemplateDelete(params: any) {
return request.post({ url: '/marketing.marketing_custom_return_visit_template/delete', params })
}
// 市场经营--客户回访模板详情
export function apiMarketingCustomReturnVisitTemplateDetail(params: any) {
return request.get({ url: '/marketing.marketing_custom_return_visit_template/detail', params })
}
// 市场经营--客户回访模板列表
export function apiMarketingCustomReturnVisitTemplateDetailLists(params: any) {
return request.get({ url: '/marketing.marketing_custom_return_visit_template_detail/lists', params })
}
// 删除市场经营--客户回访模板
export function apiMarketingCustomReturnVisitTemplateDetailDelete(params: any) {
return request.post({ url: '/marketing.marketing_custom_return_visit_template_detail/delete', params })
}
// 市场经营--客户回访模板列表
export function apiMarketingCustomReturnVisitTemplateSearch(params: any) {
return request.get({ url: '/marketing.marketing_custom_return_visit_template/datas', params })
}

View File

@ -32,3 +32,8 @@ export function apisupervision_material_parallel_testing_detail(params: any) {
export function apisupervision_material_parallel_testing_detail_check(params: any) {
return request.post({ url: '/supervision_work.supervision_material_parallel_testing_detail/check', params })
}
export function apisupervision_material_parallel_testing_delete(params: any) {
return request.post({ url: '/supervision_work.supervision_material_parallel_testing_detail/delete', params })
}

View File

@ -674,5 +674,78 @@ export const financial_borrow_money: Iconfig = {
],
};
import { apiMarketingCustomReturnVisitTemplateLists, } from '@/api/marketing_custom_return_visit_template'
export const marketing_custom_return_visit_template: Iconfig = {
fetchFn: apiMarketingCustomReturnVisitTemplateLists,
dictData:"cost_type,financial_pay_type",
serchList: [
{
label: "模板名称",
value: "name",
},
{
label: "是否启用",
value: "is_use",
select:[
{
name:'启用',
value:0
},
{
name:'不启用',
value:1
}
]
},
{
label: "模板名称",
value: "name",
},
{
label: "创建人",
value: "create_user",
},
],
tableList: [
{ name: "模板名称" },
{ is_use_text: "是否启用" },
{ create_user: "创建人" },
{ create_time: "创建时间" },
],
};
import { apiMarketingCustomReturnVisitLists, } from '@/api/marketing_custom_return_visit'
export const marketing_custom_return_visit: Iconfig = {
fetchFn: apiMarketingCustomReturnVisitLists,
dictData:'return_visit_type',
serchList: [
{
label: "回访编号",
value: "code",
},
{
label: "回访方式",
value: "return_visit_type",
select:'return_visit_type',
},
{
label: "回访人",
value: "create_user",
},
],
tableList: [
{ contract_name: "合同名称" },
{ code: "回访编号" },
{ return_visit_type_text: "回访方式" },
{ template_name: "回访表模板" },
{ create_user: "回访人" },
{ create_time: "回访日期" },
],
};

View File

@ -39,7 +39,7 @@ export function checkEmail(rules: any, value: any, callback: any) {
: callback(new Error("请输入正确的邮箱"));
}
//邮箱
//idcard
export function checkIdcard(rules: any, value: any, callback: any) {
/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(value)
? callback()

View File

@ -268,8 +268,43 @@ const submituser = (e: any) => {
showDialog3.value = false
}
const chekcDate = (rule: any, value: any, callback: any) => {
if (new Date(formData.returndate) < new Date(formData.borrow)) {
callback(new Error('印章借用日期不能早于结束借用日期'))
} else {
callback()
}
}
const chekcDate1 = (rule: any, value: any, callback: any) => {
if (new Date(formData.sjreturn) < new Date(formData.sjborrow)) {
callback(new Error('实际归还日期不能早于实际借章日期'))
} else {
callback()
}
}
//
const formRules = reactive<any>({
returndate: [{
required: true,
message: '请选择结束借用日期',
trigger: ['blur']
},
{
validator: chekcDate,
trigger: ['blur']
}],
sjreturn: [{
required: true,
message: '请选择实际归还日期',
trigger: ['blur']
},
{
validator: chekcDate1,
trigger: ['blur']
}],
})
//

View File

@ -363,7 +363,13 @@ const chekcDate = (rule: any, value: any, callback: any) => {
}
}
const chekcDate1 = (rule: any, value: any, callback: any) => {
if (new Date(formData.due_time) < new Date(formData.start_date)) {
callback(new Error('履约金到期时间不能早合同计划开始日期'))
} else {
callback()
}
}
//
const formRules = reactive<any>({
@ -406,6 +412,17 @@ const formRules = reactive<any>({
validator: chekcDate,
trigger: ['blur']
}],
due_time: [{
required: true,
message: '请输入合同计划结束日期',
trigger: ['blur']
},
{
validator: chekcDate1,
trigger: ['blur']
}],
})

View File

@ -329,6 +329,15 @@ function province_change(value: string) {
getCityList();
}
const chekcDate = (rule: any, value: any, callback: any) => {
if (new Date(formData.date) < new Date(formData.starting)) {
callback(new Error('登记日期不能早于计划开始日期'))
} else {
callback()
}
}
//
const formRules = reactive<any>({
project_name: [
@ -359,6 +368,15 @@ const formRules = reactive<any>({
trigger: ["blur"],
},
],
date: [{
required: true,
message: '请输入登记日期',
trigger: ['blur']
},
{
validator: chekcDate,
trigger: ['blur']
}],
jhgq: [
{
required: true,

View File

@ -199,8 +199,23 @@ const submituser = (e: any) => {
}
const chekcDate = (rule: any, value: any, callback: any) => {
if (new Date(formData.end_date) < new Date(formData.start_date)) {
callback(new Error('实际结束日期不能早于实际开始日期'))
} else {
callback()
}
}
//
const formRules = reactive<any>({
end_date: [
{
validator: chekcDate,
trigger: ['blur']
}],
})
@ -220,12 +235,6 @@ const setFormData = async (data: Record<any, any>) => {
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiJianliProjectProgressReportDetail({
id: row.id
})
setFormData(data)
}
//
@ -255,6 +264,5 @@ const handleClose = () => {
defineExpose({
open,
setFormData,
getDetail
})
</script>

View File

@ -51,7 +51,7 @@
<el-table-column label="登记人" prop="djr" show-overflow-tooltip />
<el-table-column label="登记时间" prop="apptime" show-overflow-tooltip />
<el-table-column label="形象进度描述" prop="jdms" show-overflow-tooltip />
<el-table-column label="操作" width="150" fixed="right" align="center">
<el-table-column label="操作" width="170" fixed="right" align="center">
<template #default="{ row }">
<el-button v-perms="['project_process_management.jianli_project_progress_report/edit']"
type="primary" link @click="handleEdit(row)">

View File

@ -0,0 +1,161 @@
import { apiMarketingCustomContactsLists } from '@/api/marketing_custom'
const detailConfig = {
title: "市场经营--客户信息",
config: [
{
label: "客户名称",
value: "name"
},
{
label: "客户简称",
value: "sub_name"
},
{
label: "客户编号",
value: "code"
},
{
label: "重要等级",
value: "important_level_text"
},
{
label: "负责部门",
value: "dept_name"
},
{
label: "客户分类",
value: "category_text"
},
{
label: "备注",
value: "remark",
column: 1
},
{
label: "开票单位",
value: "invoice_company"
},
{
label: "纳税人识别号",
value: "taxpayer_identification_number"
},
{
label: "开户银行",
value: "opening_bank"
},
{
label: "开票联系人",
value: "invoice_contact"
},
{
label: "开票单位注册地址",
value: "invoice_company_address"
},
{
label: "开票单位电话",
value: "invoice_company_telephone"
},
{
label: "开户账号",
value: "opening_bank_account"
},
{
label: "电子邮箱",
value: "email"
},
{
label: "所在省份",
value: "province_name"
},
{
label: "所在市区",
value: "city_name"
},
{
label: "邮编",
value: "post_code"
},
{
label: "电话",
value: "telephone"
},
{
label: "传真",
value: "fax"
},
{
label: "网址",
value: "website"
},
{
label: "地址",
value: "address"
},
{
label: "录入人",
value: "create_user"
},
{
label: "录入日期",
value: "create_time"
},
{
label: "附件",
value: "annex",
column: 1
},
],
table: {
title: "联系人",
tableConfig: [
{
label: "姓名",
value: 'name',
},
{
label: "部门",
value: 'dept'
},
{
label: "性别",
value: 'gender_text',
},
{
label: "职务",
value: 'job',
},
{
label: "手机",
value: 'mobile',
},
{
label: "电话",
value: 'telephone',
},
{
label: "邮箱",
value: 'email',
},
{
label: "qq",
value: 'qq',
},
{
label: "备注",
value: 'remark',
},
],
query: 'custom_id',
fetchFun: apiMarketingCustomContactsLists,
}
}
export default detailConfig;

View File

@ -0,0 +1,486 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="80vw" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="160px" :rules="formRules">
<el-row>
<el-col :span="8">
<el-form-item label="客户名称" prop="name">
<el-input v-model="formData.name" clearable placeholder="请输入客户名称" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="客户简称">
<el-input v-model="formData.sub_name" clearable placeholder="请输入客户简称" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="客户编号">
<el-input v-model="formData.code" clearable placeholder="请输入客户编号" v-type="'code'" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="重要等级" prop="important_level">
<el-select v-model="formData.important_level" placeholder="请选择重要等级" class=" flex-1">
<el-option :label="item.name" :value="parseInt(item.value)"
v-for="item in dictData.custom_important_level">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="负责部门" prop="dept_id">
<el-select v-model="formData.dept_id" placeholder="请选择部门" class="flex-1">
<el-option :label="item.name" :value="item.id" v-for="item in deptList">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="客户分类" prop="category">
<el-select v-model="formData.category" placeholder="请选择客户分类" class=" flex-1">
<el-option :label="item.name" :value="(item.value)"
v-for="item in dictData.custom_category">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="备注">
<el-input v-model="formData.remark" clearable placeholder="请输入备注" type="textarea" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="开票单位">
<el-input v-model="formData.invoice_company" clearable placeholder="请输入开票单位" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="纳税人识别号">
<el-input v-model="formData.taxpayer_identification_number" clearable placeholder="请输入纳税人识别号" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="开户银行">
<el-input v-model="formData.opening_bank" clearable placeholder="请输入开户银行" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="开票联系人">
<el-input v-model="formData.invoice_contact" clearable placeholder="请输入开票联系人" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="开票单位注册地址">
<el-input v-model="formData.invoice_company_address" clearable placeholder="请输入开票单位注册地址" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="开票单位电话">
<el-input v-model="formData.invoice_company_telephone" clearable placeholder="请输入开票单位电话" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="开户账号">
<el-input v-model="formData.opening_bank_account" clearable placeholder="请输入开户账号"
type="number" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="电子邮箱" prop="email">
<el-input v-model="formData.email" clearable placeholder="请输入电子邮箱" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="所在省份" prop="province">
<el-select v-model="formData.province" clearable placeholder="请选择省" @change="province_change"
class="flex-1">
<el-option v-for="(item, index) in datas.provinceOptions" :key="index"
:label="item.province_name" :value="(item.province_code)" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="所在市区" prop="city">
<el-select v-model="formData.city" clearable placeholder="请选择市" class="flex-1">
<el-option v-for="(item, index) in datas.cityOptions" :key="index" :label="item.city_name"
:value="(item.city_code)" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="邮编">
<el-input v-model="formData.post_code" clearable placeholder="请输入邮编" type="number" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="电话" prop="telephone">
<el-input v-model="formData.telephone" clearable placeholder="请输入电话" type="number" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="传真">
<el-input v-model="formData.fax" clearable placeholder="请输入传真" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="网址">
<el-input v-model="formData.website" clearable placeholder="请输入网址" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="地址">
<el-input v-model="formData.address" clearable placeholder="请输入地址" />
</el-form-item>
</el-col>
<CreateUserLable :form-data="formData" flag name="录入"></CreateUserLable>
<el-col :span="24">
<el-form-item label="附件">
<UploadAnnex :form-data="formData"></UploadAnnex>
</el-form-item>
</el-col>
</el-row>
<formTable :formData="formData.detail" :config="tableConfig" :dictData="dictData">
</formTable>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="marketingCustomEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiMarketingCustomAdd, apiMarketingCustomEdit, apiMarketingCustomDetail, apiMarketingCustomContactsLists, apiMarketingCustomContactsDelete } from '@/api/marketing_custom'
import { checkPhone, checkEmail } from "@/utils/validate"
import type { PropType } from 'vue'
import { apiCityList, apiProvinceList } from "@/api/common";
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
},
deptList: Array
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
//
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑市场经营--客户信息' : '新增市场经营--客户信息'
})
const datas = reactive({
provinceOptions: [],
cityOptions: [],
});
//
const formData = reactive({
id: '',
name: '',
sub_name: '',
code: '',
important_level: '',
dept_id: '',
category: '',
remark: '',
invoice_company: '',
taxpayer_identification_number: '',
opening_bank: '',
invoice_contact: '',
invoice_company_address: '',
invoice_company_telephone: '',
opening_bank_account: '',
email: '',
province: '',
city: '',
post_code: '',
telephone: '',
fax: '',
website: '',
address: '',
annex: '',
create_user: '',
create_time: '',
detail: [
{
"name": "",
"dept": "",
"gender": 0,
"job": "",
"mobile": "",
"telephone": "",
"email": "",
"qq": "",
"remark": ""
}
]
})
const tableConfig = reactive(
{
title: "联系人",
tableConfig: [
{
label: "姓名",
value: 'name',
},
{
label: "部门",
value: 'dept',
},
{
label: "性别",
value: 'gender',
select: [{
name: '男',
value: 0
},
{
name: '女',
value: 1
},
]
},
{
label: "职务",
value: 'job',
},
{
label: "手机",
value: 'mobile',
check: ['detail', checkPhone]
},
{
label: "电话",
value: 'telephone',
},
{
label: "邮箱",
value: 'email',
check: ['detail', checkEmail]
},
{
label: "qq",
value: 'qq',
},
{
label: "备注",
value: 'remark',
},
],
deleteApi: apiMarketingCustomContactsDelete,
}
)
//
const formRules = reactive<any>({
name: [{
required: true,
message: '请输入客户名称',
trigger: ['blur']
}],
sub_name: [{
required: true,
message: '请输入客户简称',
trigger: ['blur']
}],
code: [{
required: true,
message: '请输入客户编号',
trigger: ['blur']
}],
important_level: [{
required: true,
message: '请输入重要等级',
trigger: ['blur']
}],
dept_id: [{
required: true,
message: '请输入负责部门',
trigger: ['blur']
}],
category: [{
required: true,
message: '请输入客户分类',
trigger: ['blur']
}],
invoice_company: [{
required: true,
message: '请输入开票单位',
trigger: ['blur']
}],
taxpayer_identification_number: [{
required: true,
message: '请输入纳税人识别号',
trigger: ['blur']
}],
opening_bank: [{
required: true,
message: '请输入开户银行',
trigger: ['blur']
}],
invoice_contact: [{
required: true,
message: '请输入开票联系人',
trigger: ['blur']
}],
invoice_company_address: [{
required: true,
message: '请输入开票单位注册地址',
trigger: ['blur']
}],
invoice_company_telephone: [{
required: true,
message: '请输入开票单位电话',
trigger: ['blur']
}],
opening_bank_account: [{
required: true,
message: '请输入开户账号',
trigger: ['blur']
}],
email: [{
required: true,
message: '请输入电子邮箱',
trigger: ['blur']
},
{
validator: checkEmail,
trigger: ['blur']
}],
province: [{
required: true,
message: '请输入省份',
trigger: ['blur']
}],
city: [{
required: true,
message: '请输入城市',
trigger: ['blur']
}],
post_code: [{
required: true,
message: '请输入邮编',
trigger: ['blur']
}],
telephone: [{
required: true,
message: '请输入电话',
trigger: ['blur']
},
{
validator: checkPhone,
trigger: ['blur']
}],
fax: [{
required: true,
message: '请输入传真',
trigger: ['blur']
}],
website: [{
required: true,
message: '请输入网址',
trigger: ['blur']
}],
address: [{
required: true,
message: '请输入地址',
trigger: ['blur']
}],
create_user: [{
required: true,
message: '请输入录入人',
trigger: ['blur']
}],
create_time: [{
required: true,
message: '请输入录入日期',
trigger: ['blur']
}]
})
//
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]
}
}
let res = await apiMarketingCustomContactsLists({ custom_id: data.id })
formData.detail = res.lists
getCityList();
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiMarketingCustomDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
? await apiMarketingCustomEdit(data)
: await apiMarketingCustomAdd(data)
popupRef.value?.close()
emit('success')
}
//
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
const getProvinceList = async () => {
const data = await apiProvinceList({});
datas["provinceOptions"] = data;
};
const getCityList = async () => {
const data = await apiCityList({ province_code: formData.province });
datas["cityOptions"] = data;
};
//
function province_change(value: string) {
getCityList();
}
getProvinceList()
defineExpose({
open,
setFormData,
getDetail
})
</script>

View File

@ -0,0 +1,230 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form class="mb-[-16px]" :model="queryParams" label-width="80px">
<el-row>
<el-col :span="6">
<el-form-item label="客户名称" prop="name">
<el-input v-model="queryParams.name" clearable placeholder="请输入客户名称" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="客户编号" prop="code">
<el-input v-model="queryParams.code" clearable placeholder="请输入客户编号" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="重要等级" prop="important_level">
<el-select v-model="queryParams.important_level" placeholder="请选择重要等级" class=" flex-1">
<el-option :label="item.name" :value="parseInt(item.value)"
v-for="item in dictData.custom_important_level">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="负责部门" prop="dept_id">
<el-select v-model="queryParams.dept_id" placeholder="请选择部门">
<el-option :label="item.name" :value="item.id" v-for="item in deptList">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="客户分类" prop="category">
<el-select v-model="queryParams.category" placeholder="请选择客户分类" class=" flex-1">
<el-option :label="item.name" :value="parseInt(item.value)"
v-for="item in dictData.custom_category">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="省份" prop="province">
<el-select v-model="queryParams.province" clearable placeholder="请选择省" @change="province_change"
class="flex-1">
<el-option v-for="(item, index) in datas.provinceOptions" :key="index"
:label="item.province_name" :value="(item.province_code)" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="城市" prop="city">
<el-select v-model="queryParams.city" clearable placeholder="请选择市" class="flex-1">
<el-option v-for="(item, index) in datas.cityOptions" :key="index" :label="item.city_name"
:value="(item.city_code)" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
<el-button v-perms="['marketing.marketing_custom/add']" type="primary" @click="handleAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
<el-button v-perms="['marketing.marketing_custom/delete']" :disabled="!selectData.length"
@click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange" border>
<el-table-column type="selection" width="55" />
<el-table-column label="客户名称" prop="name" show-overflow-tooltip />
<el-table-column label="客户编号" prop="code" show-overflow-tooltip />
<el-table-column label="重要等级" prop="important_level_text" show-overflow-tooltip />
<el-table-column label="负责部门" prop="dept_name" show-overflow-tooltip />
<el-table-column label="客户分类" prop="category_text" show-overflow-tooltip />
<el-table-column label="省份" prop="province_name" show-overflow-tooltip />
<el-table-column label="城市" prop="city_name" show-overflow-tooltip />
<el-table-column label="录入人" prop="create_user" show-overflow-tooltip />
<el-table-column label="录入日期" prop="create_time" show-overflow-tooltip />
<el-table-column label="操作" width="170" fixed="right">
<template #default="{ row }">
<el-button v-perms="['marketing.marketing_custom/edit']" type="primary" link
@click="handleEdit(row)">
编辑
</el-button>
<el-button v-perms="['marketing.marketing_custom/delete']" type="danger" link
@click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['marketing.marketing_custom/detail']" link @click="handleDetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false"
:deptList="deptList" />
<detailPage v-if="showDetail" ref="detailRef" @close="showDetail = false" :detailConfig="detailConfig" />
</div>
</template>
<script lang="ts" setup name="marketingCustomLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiMarketingCustomLists, apiMarketingCustomDelete, apiMarketingCustomDetail } from '@/api/marketing_custom'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import { deptLists } from "@/api/org/department"
import { apiCityList, apiProvinceList } from "@/api/common";
import detailConfig from './detail'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const detailRef = ref('')
//
const showEdit = ref(false)
const showDetail = ref(false)
const datas = reactive({
provinceOptions: [],
cityOptions: [],
});
//
const queryParams = reactive({
name: '',
code: '',
important_level: '',
dept_id: '',
category: '',
province: '',
city: '',
create_user: ''
})
//
const selectData = ref<any[]>([])
//
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ id }) => id)
}
//
const { dictData } = useDictData('custom_important_level,custom_category')
//
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: apiMarketingCustomLists,
params: queryParams
})
//
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add')
}
//
const handleEdit = async (data: any) => {
let res = await apiMarketingCustomDetail({ id: data.id })
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(res)
}
//
const handleDelete = async (id: number | any[]) => {
await feedback.confirm('确定要删除?')
await apiMarketingCustomDelete({ id })
getLists()
}
//
const handleDetail = async (row) => {
let res = await apiMarketingCustomDetail({ id: row.id })
showDetail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
const deptList = ref([])
const getDeptList = async () => {
let res = await deptLists()
deptList.value = res.lists
}
const getProvinceList = async () => {
const data = await apiProvinceList({});
datas["provinceOptions"] = data;
};
const getCityList = async () => {
const data = await apiCityList({ province_code: formData.province });
datas["cityOptions"] = data;
};
//
function province_change(value: string) {
getCityList();
}
getProvinceList()
getDeptList()
getLists()
</script>

View File

@ -0,0 +1,123 @@
<template>
<div class="detail-popup">
<popup ref="popupRef" title="市场经营--客户回访列表" :async="true" width="80%" @confirm="handleSubmit" @close="handleClose">
<el-descriptions :column="2" border>
<el-descriptions-item label="合同id" label-align="left" align="left" label-class-name="my-label"> {{
formData.contract_id }}</el-descriptions-item>
<el-descriptions-item label="回访编号" label-align="left" align="left" label-class-name="my-label"> {{
formData.code }}</el-descriptions-item>
<el-descriptions-item label="回访方式" label-align="left" align="left" label-class-name="my-label"> {{
formData.return_visit_type_text }}</el-descriptions-item>
<el-descriptions-item label="回访表模板" label-align="left" align="left" label-class-name="my-label"> {{
formData.template_name
}}</el-descriptions-item>
<el-descriptions-item label="回访人" label-align="left" align="left" label-class-name="my-label"> {{
formData.create_user
}}</el-descriptions-item>
<el-descriptions-item label="回访时间" label-align="left" align="left" label-class-name="my-label"> {{
formData.create_time
}}</el-descriptions-item>
<el-descriptions-item label="附件" label-align="left" align="left" label-class-name="my-label">
<annexLink :annex="formData.annex"></annexLink>
</el-descriptions-item>
</el-descriptions>
<el-card>
<template #header>
调查内容
</template>
<el-table :data="formData.survey" stripe style="width: 100%">
<el-table-column label="调查内容" prop='survey_content' />
<el-table-column label="内容说明" prop='survey_content_desc' />
<el-table-column label="评价内容" prop='evaluate_content' />
<el-table-column label="备注" prop='remark' />
</el-table>
</el-card>
<el-card>
<template #header>
项目成员评价
</template>
<el-table :data="formData.evaluate" stripe style="width: 100%">
<el-table-column label="姓名" prop='name' />
<el-table-column label="岗位" prop='job' />
<el-table-column label="意见和建议" prop='opinions' />
</el-table>
</el-card>
</popup>
</div>
</template>
<script lang="ts" setup name="customdetail">
import Popup from '@/components/popup/index.vue'
import { apimarketing_custom_return_visit_surveyLists, apimarketing_custom_return_visit_evaluateLists } from '@/api/marketing_custom_return_visit'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const popupRef = shallowRef<InstanceType<typeof Popup>>()
//
const formData = reactive({
id: '',
contract_id: '',
code: '',
return_visit_type: '',
custom_return_visit_template_id: '',
template_name: "",
return_visit_type_text: "",
annex: '',
create_user: '',
create_time: '',
survey: [],
evaluate: []
})
//
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]
}
}
let res = await apimarketing_custom_return_visit_surveyLists({ custom_return_visit_id: data.id })
formData.survey = res.lists
let res1 = await apimarketing_custom_return_visit_evaluateLists({ custom_return_visit_id: data.id })
formData.evaluate = res1.lists
}
//
const handleSubmit = async () => {
popupRef.value?.close()
}
//
const open = () => {
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
})
</script>

View File

@ -0,0 +1,240 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="60vw" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-row>
<el-col :span="8">
<el-form-item label="合同id" prop="contract_id">
<el-input v-model="formData.contract_id" clearable placeholder="请输入合同id" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="回访编号">
<el-input v-model="formData.code" clearable placeholder="系统自动生成" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="回访方式" prop="return_visit_type">
<el-select v-model="formData.return_visit_type" placeholder="请选择回访方式" class=" flex-1">
<el-option :label="item.name" :value="parseInt(item.value)"
v-for="item in dictData.return_visit_type">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="回访表模板">
<el-input v-model="formData.template_name" clearable placeholder="点击选择回访模版"
@click="showDialog = true" readonly />
</el-form-item>
</el-col>
<CreateUserLable :form-data="formData" flag name="回访"></CreateUserLable>
<el-col :span="24">
<el-form-item label="附件" prop="annex">
<UploadAnnex :form-data="formData"></UploadAnnex>
</el-form-item>
</el-col>
</el-row>
<el-dialog v-model="showDialog" title="选择项目" width="70%">
<dialogTable :config="marketing_custom_return_visit_template" @customEvent="customEvent">
</dialogTable>
</el-dialog>
<formTable :formData="formData.survey" :config="tableConfig" />
<formTable :formData="formData.evaluate" :config="tableConfig1" />
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="marketingCustomReturnVisitEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiMarketingCustomReturnVisitAdd, apiMarketingCustomReturnVisitEdit, apiMarketingCustomReturnVisitDetail, apimarketing_custom_return_visit_surveyLists, apimarketing_custom_return_visit_surveytDelete, apimarketing_custom_return_visit_evaluateLists, apimarketing_custom_return_visit_evaluateDelete } from '@/api/marketing_custom_return_visit'
import { marketing_custom_return_visit_template } from "@/components/dialogTable/dialogTableConfig"
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 mode = ref('add')
const showDialog = ref(false)
//
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑市场经营--客户回访列表' : '新增市场经营--客户回访列表'
})
//
const formData = reactive({
id: '',
contract_id: '',
code: '',
return_visit_type: '',
custom_return_visit_template_id: '',
template_name: "",
annex: '',
create_user: '',
create_time: '',
survey: [],
evaluate: []
})
const tableConfig = reactive(
{
title: "调查内容",
tableConfig: [
{
label: "调查内容",
value: 'survey_content',
},
{
label: "内容说明",
value: 'survey_content_desc',
},
{
label: "评价内容",
value: 'evaluate_content',
},
{
label: "备注",
value: 'remark',
},
],
deleteApi: apimarketing_custom_return_visit_surveytDelete,
}
)
const tableConfig1 = reactive(
{
title: "项目成员评价",
tableConfig: [
{
label: "姓名",
value: 'name',
},
{
label: "岗位",
value: 'job',
},
{
label: "意见和建议",
value: 'opinions',
},
],
deleteApi: apimarketing_custom_return_visit_evaluateDelete,
}
)
const customEvent = (e: any) => {
formData.custom_return_visit_template_id = e.id
formData.template_name = e.name
showDialog.value = false
}
//
const formRules = reactive<any>({
contract_id: [{
required: true,
message: '请输入合同id',
trigger: ['blur']
}],
code: [{
required: true,
message: '请输入回访编号',
trigger: ['blur']
}],
return_visit_type: [{
required: true,
message: '请输入回访方式',
trigger: ['blur']
}],
custom_return_visit_template_id: [{
required: true,
message: '请输入回访表模板',
trigger: ['blur']
}],
create_user: [{
required: true,
message: '请输入回访人',
trigger: ['blur']
}],
create_time: [{
required: true,
message: '请输入回访日期',
trigger: ['blur']
}]
})
//
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]
}
}
let res = await apimarketing_custom_return_visit_surveyLists({ custom_return_visit_id: data.id })
formData.survey = res.lists
let res1 = await apimarketing_custom_return_visit_evaluateLists({ custom_return_visit_id: data.id })
formData.evaluate = res1.lists
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiMarketingCustomReturnVisitDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
? await apiMarketingCustomReturnVisitEdit(data)
: await apiMarketingCustomReturnVisitAdd(data)
popupRef.value?.close()
emit('success')
}
//
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>

View File

@ -0,0 +1,163 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<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>
<el-form-item label="回访编号" prop="code">
<el-input class="w-[280px]" v-model="queryParams.code" clearable placeholder="请输入回访编号" />
</el-form-item>
<el-form-item label="回访方式" prop="return_visit_type">
<el-select v-model="queryParams.return_visit_type" placeholder="请选择回访方式" class=" flex-1">
<el-option :label="item.name" :value="(item.value)" v-for="item in dictData.return_visit_type">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="回访表模板" prop="custom_return_visit_template_id">
<!-- <el-input class="w-[280px]" v-model="queryParams.custom_return_visit_template_id" clearable
placeholder="请输入回访表模板" /> -->
<selectRemote :formData="queryParams" model="custom_return_visit_template_id"
:api="apiMarketingCustomReturnVisitTemplateSearch">
</selectRemote>
</el-form-item>
<el-form-item label="回访人" prop="create_user">
<el-input class="w-[280px]" v-model="queryParams.create_user" clearable placeholder="请输入回访人" />
</el-form-item>
<el-form-item label="回访日期" prop="create_time">
<el-input class="w-[280px]" v-model="queryParams.create_time" 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">
<el-button v-perms="['marketing.marketing_custom_return_visit/add']" type="primary" @click="handleAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
<el-button v-perms="['marketing.marketing_custom_return_visit/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="合同名称" prop="contract_id" show-overflow-tooltip />
<el-table-column label="回访编号" prop="code" show-overflow-tooltip />
<el-table-column label="回访方式" prop="return_visit_type_text" show-overflow-tooltip />
<el-table-column label="回访表模板" prop="template_name" show-overflow-tooltip />
<el-table-column label="回访人" prop="create_user" show-overflow-tooltip />
<el-table-column label="回访日期" prop="create_time" show-overflow-tooltip />
<el-table-column label="操作" width="170" fixed="right">
<template #default="{ row }">
<el-button v-perms="['marketing.marketing_custom_return_visit/edit']" type="primary" link
@click="handleEdit(row)">
编辑
</el-button>
<el-button v-perms="['marketing.marketing_custom_return_visit/delete']" type="danger" link
@click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['marketing.marketing_custom_return_visit/detail']" link
@click="handleDetail(row.id)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex mt-4 justify-end">
<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="showDetail" ref="detailRef" :dict-data="dictData" @close="showDetail = false" />
</div>
</template>
<script lang="ts" setup name="marketingCustomReturnVisitLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiMarketingCustomReturnVisitLists, apiMarketingCustomReturnVisitDelete, apiMarketingCustomReturnVisitDetail } from '@/api/marketing_custom_return_visit'
import { apiMarketingCustomReturnVisitTemplateSearch, } from '@/api/marketing_custom_return_visit_template'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import detailPopup from './detail.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const detailRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
const showDetail = ref(false)
//
const queryParams = reactive({
contract_id: '',
code: '',
return_visit_type: '',
custom_return_visit_template_id: '',
create_user: '',
create_time: ''
})
//
const selectData = ref<any[]>([])
//
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ id }) => id)
}
//
const { dictData } = useDictData('return_visit_type')
//
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: apiMarketingCustomReturnVisitLists,
params: queryParams
})
//
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add')
}
//
const handleEdit = async (data: any) => {
let res = await apiMarketingCustomReturnVisitDetail({ id: data.id })
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(res)
}
//
const handleDelete = async (id: number | any[]) => {
await feedback.confirm('确定要删除?')
await apiMarketingCustomReturnVisitDelete({ id })
getLists()
}
//
const handleDetail = async (data: any) => {
let res = await apiMarketingCustomReturnVisitDetail({ id: data })
showDetail.value = true
await nextTick()
detailRef.value?.open('edit')
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -0,0 +1,145 @@
<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="120px" :rules="formRules">
<el-form-item label="客户回访编号" prop="custom_return_visit_code">
<el-input v-model="formData.custom_return_visit_code" clearable placeholder="点击选择客户回访编号" readonly
@click="showDialog = true" />
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input v-model="formData.name" clearable placeholder="请输入姓名" />
</el-form-item>
<el-form-item label="岗位" prop="job">
<el-input v-model="formData.job" clearable placeholder="请输入岗位" />
</el-form-item>
<el-form-item label="意见和建议" prop="opinions">
<el-input v-model="formData.opinions" clearable placeholder="请输入意见和建议" type="textarea" />
</el-form-item>
</el-form>
<el-dialog v-model="showDialog" title="选择回访编号" width="70%">
<dialogTable :config="marketing_custom_return_visit" @customEvent="customEvent">
</dialogTable>
</el-dialog>
</popup>
</div>
</template>
<script lang="ts" setup name="marketingCustomReturnVisitEvaluateEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiMarketingCustomReturnVisitEvaluateAdd, apiMarketingCustomReturnVisitEvaluateEdit, apiMarketingCustomReturnVisitEvaluateDetail } from '@/api/marketing_custom_return_visit_evaluate'
import { marketing_custom_return_visit } from "@/components/dialogTable/dialogTableConfig"
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 mode = ref('add')
const showDialog = ref(false)
//
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑市场经营--客户回访列表--成员评价' : '新增市场经营--客户回访列表--成员评价'
})
//
const formData = reactive({
id: '',
custom_return_visit_id: '',
custom_return_visit_code: '',
name: '',
job: '',
opinions: '',
})
const customEvent = (e: any) => {
formData.custom_return_visit_id = e.id
formData.custom_return_visit_code = e.code
showDialog.value = false
}
//
const formRules = reactive<any>({
custom_return_visit_id: [{
required: true,
message: '请输入客户回访id',
trigger: ['blur']
}],
name: [{
required: true,
message: '请输入姓名',
trigger: ['blur']
}],
job: [{
required: true,
message: '请输入岗位',
trigger: ['blur']
}],
opinions: [{
required: true,
message: '请输入意见和建议',
trigger: ['blur']
}]
})
//
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]
}
}
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiMarketingCustomReturnVisitEvaluateDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
? await apiMarketingCustomReturnVisitEvaluateEdit(data)
: await apiMarketingCustomReturnVisitEvaluateAdd(data)
popupRef.value?.close()
emit('success')
}
//
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>

View File

@ -0,0 +1,119 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="客户回访id" prop="custom_return_visit_id">
<el-input class="w-[280px]" v-model="queryParams.custom_return_visit_id" clearable
placeholder="请输入客户回访id" />
</el-form-item>
<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">
<el-button v-perms="['marketing.marketing_custom_return_visit_evaluate/add']" type="primary" @click="handleAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
<el-button v-perms="['marketing.marketing_custom_return_visit_evaluate/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="custom_return_visit_id" show-overflow-tooltip />
<el-table-column label="姓名" prop="name" show-overflow-tooltip />
<el-table-column label="岗位" prop="job" show-overflow-tooltip />
<el-table-column label="意见和建议" prop="opinions" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button v-perms="['marketing.marketing_custom_return_visit_evaluate/edit']" type="primary"
link @click="handleEdit(row)">
编辑
</el-button>
<el-button v-perms="['marketing.marketing_custom_return_visit_evaluate/delete']" type="danger"
link @click="handleDelete(row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup name="marketingCustomReturnVisitEvaluateLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiMarketingCustomReturnVisitEvaluateLists, apiMarketingCustomReturnVisitEvaluateDelete, apiMarketingCustomReturnVisitEvaluateDetail } from '@/api/marketing_custom_return_visit_evaluate'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
//
const showEdit = ref(false)
//
const queryParams = reactive({
custom_return_visit_id: '',
name: ''
})
//
const selectData = ref<any[]>([])
//
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ id }) => id)
}
//
const { dictData } = useDictData('')
//
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: apiMarketingCustomReturnVisitEvaluateLists,
params: queryParams
})
//
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add')
}
//
const handleEdit = async (data: any) => {
let res = await apiMarketingCustomReturnVisitEvaluateDetail({ id: data.id })
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(res)
}
//
const handleDelete = async (id: number | any[]) => {
await feedback.confirm('确定要删除?')
await apiMarketingCustomReturnVisitEvaluateDelete({ id })
getLists()
}
getLists()
</script>

View File

@ -0,0 +1,46 @@
import { apiMarketingCustomReturnVisitTemplateDetailLists } from '@/api/marketing_custom_return_visit_template'
const detailConfig = {
title: "市场经营--客户回访模板",
config: [
{
label: "模板名称",
value: "name"
},
{
label: "是否启用",
value: "is_use_text"
},
{
label: "创建人",
value: "create_user"
},
{
label: "创建日期",
value: "create_time"
},
],
table: {
title: "回访内容",
tableConfig: [
{
label: "调查内容",
value: 'survey_content',
},
{
label: "内容说明",
value: 'survey_content_desc'
},
],
query: 'custom_return_visit_template_id',
fetchFun: apiMarketingCustomReturnVisitTemplateDetailLists,
}
}
export default detailConfig;

View File

@ -0,0 +1,152 @@
<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="模板名称" prop="name">
<el-input v-model="formData.name" clearable placeholder="请输入模板名称" />
</el-form-item>
<el-form-item label="是否启用 " prop="is_use">
<el-select v-model="formData.is_use" class="flex-1">
<el-option label="启用" :value="0"></el-option>
<el-option label="不启用" :value="1"></el-option>
</el-select>
</el-form-item>
<CreateUserLable :form-data="formData"></CreateUserLable>
<formTable :formData="formData.detail" :config="tableConfig" :dictData="dictData">
</formTable>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="marketingCustomReturnVisitTemplateEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiMarketingCustomReturnVisitTemplateAdd, apiMarketingCustomReturnVisitTemplateEdit, apiMarketingCustomReturnVisitTemplateDetail, apiMarketingCustomReturnVisitTemplateDetailLists, apiMarketingCustomReturnVisitTemplateDetailDelete } from '@/api/marketing_custom_return_visit_template'
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 mode = ref('add')
//
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑市场经营--客户回访模板' : '新增市场经营--客户回访模板'
})
//
const formData = reactive({
id: '',
name: '',
is_use: '',
create_user: '',
create_time: '',
detail: []
})
const tableConfig = reactive(
{
title: "回访内容",
tableConfig: [
{
label: "调查内容",
value: 'survey_content',
},
{
label: "内容说明",
value: 'survey_content_desc',
},
],
deleteApi: apiMarketingCustomReturnVisitTemplateDetailDelete,
}
)
//
const formRules = reactive<any>({
name: [{
required: true,
message: '请输入模板名称',
trigger: ['blur']
}],
is_use: [{
required: true,
message: '请输入是否启用',
trigger: ['blur']
}],
create_user: [{
required: true,
message: '请输入创建人',
trigger: ['blur']
}],
create_time: [{
required: true,
message: '请输入',
trigger: ['blur']
}]
})
//
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]
}
}
let res = await apiMarketingCustomReturnVisitTemplateDetailLists({ custom_return_visit_template_id: data.id })
formData.detail = res.lists
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiMarketingCustomReturnVisitTemplateDetail({
id: row.id
})
setFormData(data)
}
//
const handleSubmit = async () => {
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
? await apiMarketingCustomReturnVisitTemplateEdit(data)
: await apiMarketingCustomReturnVisitTemplateAdd(data)
popupRef.value?.close()
emit('success')
}
//
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
}
//
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>

View File

@ -0,0 +1,143 @@
<template>
<div>
<el-card class="!border-none mb-4" 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 label="是否启用" prop="is_use">
<el-select v-model="queryParams.is_use" class="flex-1">
<el-option label="启用" :value="0"></el-option>
<el-option label="不启用" :value="1"></el-option>
</el-select>
</el-form-item>
<el-form-item label="创建人" prop="create_user">
<el-input class="w-[280px]" v-model="queryParams.create_user" 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">
<el-button v-perms="['marketing.marketing_custom_return_visit_template/add']" type="primary" @click="handleAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
<el-button v-perms="['marketing.marketing_custom_return_visit_template/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="模板名称" prop="name" show-overflow-tooltip />
<el-table-column label="是否启用" prop="is_use_text" show-overflow-tooltip />
<el-table-column label="创建人" prop="create_user" show-overflow-tooltip />
<el-table-column label="创建时间" prop="create_time" show-overflow-tooltip />
<el-table-column label="操作" width="170" fixed="right">
<template #default="{ row }">
<el-button v-perms="['marketing.marketing_custom_return_visit_template/edit']" type="primary"
link @click="handleEdit(row)">
编辑
</el-button>
<el-button v-perms="['marketing.marketing_custom_return_visit_template/delete']" type="danger"
link @click="handleDelete(row.id)">
删除
</el-button>
<el-button v-perms="['marketing.marketing_custom_return_visit_template/detail']" link
@click="handleDetail(row)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
<detailPage v-if="showDetail" ref="detailRef" @close="showDetail = false" :detailConfig="detailConfig" :column="1"
width="550px" />
</div>
</template>
<script lang="ts" setup name="marketingCustomReturnVisitTemplateLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiMarketingCustomReturnVisitTemplateLists, apiMarketingCustomReturnVisitTemplateDelete, apiMarketingCustomReturnVisitTemplateDetail } from '@/api/marketing_custom_return_visit_template'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import detailConfig from './detail'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const detailRef = ref('')
//
const showEdit = ref(false)
const showDetail = ref(false)
//
const queryParams = reactive({
name: '',
is_use: '',
create_user: ''
})
//
const selectData = ref<any[]>([])
//
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ id }) => id)
}
//
const { dictData } = useDictData('')
//
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: apiMarketingCustomReturnVisitTemplateLists,
params: queryParams
})
//
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add')
}
//
const handleEdit = async (data: any) => {
let res = await apiMarketingCustomReturnVisitTemplateDetail({ id: data.id })
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(res)
}
//
const handleDelete = async (id: number | any[]) => {
await feedback.confirm('确定要删除?')
await apiMarketingCustomReturnVisitTemplateDelete({ id })
getLists()
}
//
const handleDetail = async (row) => {
let res = await apiMarketingCustomReturnVisitTemplateDetail({ id: row.id })
showDetail.value = true
await nextTick()
detailRef.value?.open()
detailRef.value?.setFormData(res)
}
getLists()
</script>

View File

@ -51,9 +51,9 @@
</el-table-column>
</el-table>
</div>
<div class="flex justify-end mt-4">
<!-- <div class="flex justify-end mt-4">
<pagination v-model="pager" @change="getLists" />
</div>
</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" />
@ -64,10 +64,6 @@
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apimaterialLists, apimaterialDelete, apimaterialDetail } from '@/api/material_classify'
import { timeFormat } from '@/utils/util'
import { apiContractLists } from '@/api/contract'
import { apiCustomLists } from '@/api/custom'
import { getAllProjectTypes } from '@/api/projecttype'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import DetailPopup from './detail.vue'
@ -81,6 +77,7 @@ const showDtail = ref(false)
//
const queryParams = reactive({
name: '',
page_size: 2000

View File

@ -180,7 +180,7 @@
<el-table-column label="备注" prop="remark" width="200px">
<template #default="{ row }">
<el-input v-model="row.remark" type="number" />
<el-input v-model="row.remark" />
</template>
</el-table-column>
</el-table>

View File

@ -41,6 +41,13 @@
<el-table-column label="发票形式" prop="invoice_form_text" show-overflow-tooltip width="100" />
<el-table-column label="发票金额" prop="invoice_amount" show-overflow-tooltip />
<el-table-column label="备注" prop="remark" show-overflow-tooltip />
<el-table-column label="附件" prop="annex" show-overflow-tooltip>
<template #default="{ row }">
<div v-for="item, index in row.annex" :key="index">
<el-link :href="item.uri" type="primary" target="_blank"> {{ item.name }}</el-link>
</div>
</template>
</el-table-column>
</el-table>
</div>
</el-card>

View File

@ -27,30 +27,15 @@
<el-col :span="8">
<el-form-item label="合同金额(元)" prop="contract_amount"
:rules="[{ required: true, message: '不可为空', trigger: 'blur' }]">
<el-input v-model="formData.contract_amount" type="number" @change="getSummaries" clearable
placeholder="请输入合同金额(元)" />
<el-input v-model="formData.contract_amount" type="number" 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="project_amount" clearable disabled 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="project_rate" clearable disabled placeholder="请输入项目利润率(%)" />
</el-form-item>
</el-col>
</el-row>
<br />
<!-- <el-row>
<el-row>
<el-table :data="tableData" :summary-method="getSummaries" show-summary>
<el-table-column label="序号" type="index" width="56">
<el-table-column label="序号" type="index" width="120">
</el-table-column>
<el-table-column label="分项">
<template #default="{ row, $index }">
@ -59,18 +44,17 @@
</template>
</el-table-column>
<el-table-column label="预算成本" prop="cost">
<template #default="{ row, $index }">
<el-input v-model="row.cost" @input="costinput(row, $index)" /> </template>
<el-input v-model="formData[row.value]" @change="calColumnRate" />
</template>
</el-table-column>
<el-table-column label="成本占比" prop="rate" width="156">
<template #default="{ row }">
{{ row.rate }}
</template>
</el-table-column>
</el-table>
</el-row> -->
</el-row>
<el-row style="margin: 20px 0;">
<el-col :span="24">
@ -116,90 +100,64 @@
</template>
<script lang="ts" setup name="projectEdit">
import customDialog from '@/components/custom-dialog/index.vue'
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import salescontractDialog from '@/components/salescontract/index.vue'
import projectDialog from '@/components/project/index.vue'
import type { TableColumnCtx } from 'element-plus'
import { apiProjectbudgetAdd, apiProjectbudgetEdit, apiProjectbudgetDetail } from '@/api/project_total_budget'
import { toChinesNum } from "@/utils/util";
import { getAllProjectTypes } from '@/api/projecttype'
import { timeFormat } from '@/utils/util'
import { isEmail, isIdCard, isPhone } from '@/utils/validate'
import { deptAll } from '@/api/org/department'
import { getAll } from '@/api/org/organization'
import type { PropType } from 'vue'
import configs from "@/config"
import useUserStore from "@/stores/modules/user";
import { number } from 'echarts/core'
const protype = reactive([])
const base_url = configs.baseUrl + configs.urlPrefix
const userStore = useUserStore();
const active = ref(0)
const formDataannex = reactive([])
const list1 = reactive([])
const list2 = reactive([])
const project_amount = ref(0)
const project_rate = ref(0)
// const tableData = reactive([{
// name: "/()",
// text: '',
// cost: "", rate: "",
// cl_cost: ''
// },
// {
// name: "()",
// text: '', cost: "", rate: "",
// fb_cost: '',
// },
// {
// name: "()",
// text: '', cost: "", rate: "",
// rg_cost: ''
// },
// {
// name: "()",
// text: '', cost: "", rate: "",
// fy_cost: ''
// },
// {
// name: " & ()",
// text: '', cost: "", rate: "",
// jj_cost: ''
// },
const tableData = reactive([{
name: "材料/设备成本(元)",
text: '用于控制材料成本',
rate: "",
value: 'cl_cost',
},
{
name: "分包成本(元)",
text: '用于控制分包成本',
rate: "",
value: 'fb_cost',
// ])
},
{
name: "人工成本(元)",
text: '用于控制工时成本及项目人力成本',
rate: "",
value: 'rg_cost',
},
{
name: "费用成本(元)",
text: '用于控制费用报销及差旅报销',
rate: "",
value: 'fy_cost',
},
{
name: "机械 & 工具成本(元)",
text: '用于控制机械及设备成本',
rate: "",
value: 'jj_cost',
},
])
const contract_name = ref('')
const project_name = ref('')
const project_code = ref('')
const contract_no = ref('')
const custom_name = ref('')
const manage_name = ref('')
const userInfo = userStore.userInfo
const personnel = ref<any>()
//
const checkPhone = (rule: any, value: any, callback: (arg0: Error) => any) => {
if (value && !/^1\d{10}$/.test(value)) {
callback(new Error('请输入正确的手机号码'));
} else {
callback()
}
}
const userEmail = (rule: any, value: string, callback: (arg0: Error | undefined) => void) => {
if (value && !mailReg.test(value)) {
callback(new Error('请输入正确的邮箱格式'))
} else {
callback()
}
};
defineProps({
dictData: {
@ -211,15 +169,10 @@ const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<Popup>>()
const mode = ref('add')
const totalenum = ref('')
const showDialog = ref(false)
const showDialog1 = ref(false)
const showDialog2 = ref(false)
const customEvent = (e: any) => {
formData.customer_id = e.id;
custom_name.value = e.name;
showDialog.value = false;
};
const customEvent1 = (e: any) => {
formData.contract_id = e.id;
contract_name.value = e.contract_name;
@ -234,43 +187,6 @@ const customEvent2 = (e: any) => {
custom_name.value = e.custom_name;
showDialog2.value = false;
};
// const updateCost = () => {
// for (let i = 0; i < tableData.length; i++) {
// const row = tableData[i];
// if (row.cost && row.cost > 0) {
// row.rate = (row.cost / Number(totalenum.value)).toFixed(2) + '%';
// } else {
// row.rate = ''
// }
// }
// };
//%
// const costinput = (row, index) => {
// row.rate = (row.cost / Number(totalenum.value)).toFixed(2) + '%'
// if (index == 0) {
// formData.cl_cost = row.cost
// } else if (index == 2) {
// formData.fb_cost = row.cost
// } else if (index == 3) {
// formData.rg_cost = row.cost
// } else if (index == 4) {
// formData.fy_cost = row.cost
// } else if (index == 5) {
// formData.jj_cost = row.cost
// }
// }
//
@ -283,76 +199,7 @@ const submituser = (e: any) => {
formData.project_manager = e.id;
manage_name.value = e.name;
}
// interface Product {
// id: string
// name: string
// text: string
// cost: number
// rate: string
// cl_cost: number
// }
// interface SummaryMethodProps<T = Product> {
// columns: TableColumnCtx<T>[]
// data: T[]
// }
// const getSummaries = (param: SummaryMethodProps) => {
// // FIXME
// updateCost();
// if (formData && formData.contract_amount && project_amount.value) {
// project_amount.value = Number(formData.contract_amount) - Number(project_amount.value);
// project_rate.value = (Number(project_amount.value) / Number(formData.contract_amount)).toFixed(2) + '%';
// }
// if (project_amount.value) {
// project_amount.value = Number(formData.contract_amount) - Number(project_amount.value);
// project_rate.value = (Number(project_amount.value) / Number(formData.contract_amount)).toFixed(2) + '%';
// }
// const { columns, data } = param
// const sums: string[] = []
// columns.map((column, index) => {
// if (column.label == '') {
// sums[index] = ''
// return
// }
// if (column.label == '') {
// sums[index] = ''
// return
// }
// if (column.label === '') {
// sums[index] = ''
// return
// }
// const values = data.map((item: any) => Number(item[column.property]))
// if (!values.every((value) => Number.isNaN(value))) {
// sums[index] = `${values.reduce((prev, curr) => {
// const value = Number(curr)
// if (!Number.isNaN(value)) {
// return prev + curr
// } else {
// return prev
// }
// }, 0)}`
// } else {
// sums[index] = 'N/A'
// }
// })
// totalenum.value = sums[2]
// project_amount.value = sums[2]
// return sums
// }
//
const amountinput = (e) => {
if (e && e > 0) {
formData.amount_daxie = toChinesNum(e)
}
}
//
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑总预算表' : '新增总预算表'
@ -365,11 +212,12 @@ const formData = reactive({
dept_id: "",
project_id: "",
contract_amount: 0,
cl_cost: "",
fb_cost: "",
rg_cost: "",
fy_cost: "",
jj_cost: "",
contract_id: '',
cl_cost: 0,
fb_cost: 0,
rg_cost: 0,
fy_cost: 0,
jj_cost: 0,
remark: "",
budget_list: [],
budget_date: "",
@ -428,6 +276,7 @@ const setFormData = async (data: Record<any, any>) => {
}
getlist1(formData.org_id)
calColumnRate()
}
const getDetail = async (row: Record<string, any>) => {
@ -467,27 +316,57 @@ const handleClose = () => {
emit('close')
}
// watch(
// [totalenum, project_amount, project_rate,], (newValue, oldValue) => {
// updateCost();
// if (formData && formData.contract_amount && project_amount.value) {
// project_amount.value = Number(formData.contract_amount) - Number(project_amount.value);
// project_rate.value = (Number(project_amount.value) / Number(formData.contract_amount)).toFixed(2) + '%';
// }
// },
// )
// watch(
// () => formData.contract_amount,
// (newValue, oldValue) => {
//
const totalAmout = computed(() => {
return Number(formData.cl_cost) + Number(formData.fb_cost) + Number(formData.rg_cost) + Number(formData.fy_cost) + Number(formData.jj_cost) || 0
})
//
const calColumnRate = (index) => {
tableData.forEach((item, index) => {
item.rate = Number(formData[item.value] / totalAmout.value).toFixed(2) || "0.00%"
});
}
//
const project_rate = computed(() => {
let num = ((totalAmout.value / Number(formData.contract_amount)).toFixed(2))
return (isNaN(num) ? '0.00%' : num)
})
//
const getSummaries = (param: SummaryMethodProps) => {
const { columns, data } = param
const sums: string[] = []
columns.map((column, index) => {
if (column.label == '序号') {
sums[index] = '项目利润:'
return
}
if (column.label == '分项') {
sums[index] = totalAmout.value || 0
sums[index].toFixed(2)
return
}
if (column.label == '预算成本') {
sums[index] = "项目利润率:"
return
}
if (column.label == '成本占比') {
sums[index] = project_rate.value || "0.00%"
return
}
})
return sums
}
// if (project_amount.value) {
// project_amount.value = Number(formData.contract_amount) - Number(project_amount.value);
// project_rate.value = (Number(project_amount.value) / Number(formData.contract_amount)).toFixed(2) + '%';
// }
// }
// )
defineExpose({
open,

View File

@ -47,7 +47,7 @@
</el-col>
</el-row>
<br />
<!-- <el-row>
<el-row>
<el-table :data="tableData" :summary-method="getSummaries" show-summary>
<el-table-column label="序号" type="index" width="56">
@ -70,7 +70,7 @@
</template>
</el-table-column>
</el-table>
</el-row> -->
</el-row>
<el-row style="margin: 20px 0;">
<el-col :span="24">
@ -116,7 +116,6 @@
</template>
<script lang="ts" setup name="projectEdit">
import customDialog from '@/components/custom-dialog/index.vue'
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import salescontractDialog from '@/components/salescontract/index.vue'

View File

@ -9,8 +9,8 @@
<span v-if="item.lable != '附件'"> {{ item.value.length > 1 ? formData[item.value[0]][item.value[1]] :
formData[item.value[0]]
}}</span>
<span v-else> <el-link class="m-2" v-for="item in formData.annex" :href="item.uri"
target="_blank" type='primary'>{{ item.name }}</el-link>
<span v-else> <el-link class="m-2" v-for="item in formData.annex" :href="item.uri" target="_blank"
type='primary'>{{ item.name }}</el-link>
</span>
</el-descriptions-item>
@ -46,6 +46,13 @@
<el-table-column label="发票形式" prop="invoice_form_text" show-overflow-tooltip width="100" />
<el-table-column label="发票金额" prop="invoice_amount" show-overflow-tooltip />
<el-table-column label="备注" prop="remark" show-overflow-tooltip />
<el-table-column label="附件" prop="annex" show-overflow-tooltip>
<template #default="{ row }">
<div v-for="item, index in row.annex" :key="index">
<el-link :href="item.uri" type="primary" target="_blank"> {{ item.name }}</el-link>
</div>
</template>
</el-table-column>
</el-table>
</div>
</el-card>

View File

@ -1,7 +1,6 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="80vw" @confirm="handleSubmit"
@close="handleClose">
<popup ref="popupRef" :title="popupTitle" :async="true" width="80vw" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-row>
<el-col :span="8">
@ -42,7 +41,8 @@
</el-col>
</el-row>
<el-dialog v-model="showDialog2" title="选择来源单据" width="70%">
<dialogTable :config="supervision_material_entry" @customEvent="customEvent1"></dialogTable>
<dialogTable :config="supervision_material_entry" @customEvent="customEvent1"
:query="{ parallel_test: 1 }"></dialogTable>
</el-dialog>
</el-form>
<formTable :formData="formData.detail" :config="tableConfig"></formTable>
@ -53,7 +53,7 @@
<script lang="ts" setup name="supervisionWitnessSamplingEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiSupervisionMaterialParallelTestingAdd, apiSupervisionMaterialParallelTestingEdit, apisupervision_material_parallel_testing_detail } from '@/api/supervision_material_parallel_testing'
import { apiSupervisionMaterialParallelTestingAdd, apiSupervisionMaterialParallelTestingEdit, apisupervision_material_parallel_testing_detail, apisupervision_material_parallel_testing_delete } from '@/api/supervision_material_parallel_testing'
import { apisupervision_material_entry_detail } from '@/api/supervision_material_entry'
import type { PropType } from 'vue'
import { supervision_material_entry } from "@/components/dialogTable/dialogTableConfig"
@ -137,6 +137,7 @@ const tableConfig = reactive(
value: 'num',
},
],
deleteApi: apisupervision_material_parallel_testing_delete
}
)

View File

@ -1,9 +1,7 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="80vw" @confirm="handleSubmit"
@close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules"
:disabled="mode == 'detail'">
<popup ref="popupRef" :title="popupTitle" :async="true" width="80vw" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules" :disabled="mode == 'detail'">
<el-row>
<el-col :span="8">
<el-form-item label="项目名称" prop="project_name">
@ -58,14 +56,13 @@
</el-col>
<el-col :span="8">
<el-form-item label="总投资(元)" label-width="120px">
<el-input v-model="formData.total_investment" clearable placeholder="请输入总投资(元)"
type="number" />
<el-input v-model="formData.total_investment" clearable placeholder="请输入总投资(元)" type="number" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="立项日期">
<el-date-picker class="flex-1 !flex" v-model="formData.initiation_date" clearable
type="date" value-format="YYYY-MM-DD" placeholder="请选择日期">
<el-date-picker class="flex-1 !flex" v-model="formData.initiation_date" clearable type="date"
value-format="YYYY-MM-DD" placeholder="请选择日期">
</el-date-picker>
</el-form-item>
</el-col>
@ -77,36 +74,35 @@
</el-col>
<el-col :span="8">
<el-form-item label="合同金额">
<el-input v-model="formData.contract_amount" clearable placeholder="请输入合同金额"
type="number" />
<el-input v-model="formData.contract_amount" clearable placeholder="请输入合同金额" type="number" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="实际开工日期" label-width="120px">
<el-date-picker class="flex-1 !flex" v-model="formData.actual_start_date" clearable
type="date" value-format="YYYY-MM-DD" placeholder="请选择日期">
<el-form-item label="实际开工日期" label-width="120px" prop="actual_start_date">
<el-date-picker class="flex-1 !flex" v-model="formData.actual_start_date" clearable type="date"
value-format="YYYY-MM-DD" placeholder="请选择日期">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="实际竣工日期" label-width="120px">
<el-date-picker class="flex-1 !flex" v-model="formData.actual_end_date" clearable
type="date" value-format="YYYY-MM-DD" placeholder="请选择日期">
<el-form-item label="实际竣工日期" label-width="120px" prop="actual_end_date">
<el-date-picker class="flex-1 !flex" v-model="formData.actual_end_date" clearable type="date"
value-format="YYYY-MM-DD" placeholder="请选择日期">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划开工日期" label-width="120px">
<el-date-picker class="flex-1 !flex" v-model="formData.planned_start_date" clearable
type="date" value-format="YYYY-MM-DD" placeholder="请选择日期">
<el-form-item label="计划开工日期" label-width="120px" prop="planned_start_date">
<el-date-picker class="flex-1 !flex" v-model="formData.planned_start_date" clearable type="date"
value-format="YYYY-MM-DD" placeholder="请选择日期">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="计划竣工日期" label-width="120px">
<el-date-picker class="flex-1 !flex" v-model="formData.planned_end_date" clearable
type="date" value-format="YYYY-MM-DD" placeholder="请选择日期">
<el-form-item label="计划竣工日期" label-width="120px" prop="planned_end_date">
<el-date-picker class="flex-1 !flex" v-model="formData.planned_end_date" clearable type="date"
value-format="YYYY-MM-DD" placeholder="请选择日期">
</el-date-picker>
</el-form-item>
</el-col>
@ -130,8 +126,7 @@
</el-col>
<el-col :span="8">
<el-form-item label="工程状态">
<el-select class="flex-1" v-model="formData.engineering_status" clearable
placeholder="请选择盖章名称">
<el-select class="flex-1" v-model="formData.engineering_status" clearable placeholder="请选择盖章名称">
<el-option v-for="(item, index) in dictData.supervision_project_status" :key="index"
:label="item.name" :value="parseInt(item.value)" />
</el-select>
@ -155,8 +150,8 @@
</el-col>
<el-col :span="8">
<el-form-item label="创建时间" prop="create_time">
<el-date-picker class="flex-1 !flex" v-model="formData.create_time" clearable
type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择创建时间">
<el-date-picker class="flex-1 !flex" v-model="formData.create_time" clearable type="datetime"
value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择创建时间">
</el-date-picker>
</el-form-item>
</el-col>
@ -168,8 +163,7 @@
</el-col>
<el-col :span="8">
<el-form-item label="项目概况">
<el-input v-model="formData.project_overview" clearable placeholder="请输入项目概况"
type="textarea" />
<el-input v-model="formData.project_overview" clearable placeholder="请输入项目概况" type="textarea" />
</el-form-item>
</el-col>
<el-col :span="8">
@ -256,6 +250,23 @@ const formData = reactive({
create_time: timeFormat('', 'yyyy-mm-dd hh:MM:ss'),
})
const chekcDate = (rule: any, value: any, callback: any) => {
if (new Date(formData.actual_end_date) < new Date(formData.actual_start_date)) {
callback(new Error('实际竣工日期不能早于实际开工日期'))
} else {
callback()
}
}
const chekcDate1 = (rule: any, value: any, callback: any) => {
if (new Date(formData.planned_end_date) < new Date(formData.planned_start_date)) {
callback(new Error('计划竣工日期不能早于计划开工日期'))
} else {
callback()
}
}
//
const formRules = reactive<any>({
@ -328,6 +339,10 @@ const formRules = reactive<any>({
required: true,
message: '请输入实际竣工日期',
trigger: ['blur']
},
{
validator: chekcDate,
trigger: ['blur']
}],
planned_start_date: [{
required: true,
@ -338,6 +353,10 @@ const formRules = reactive<any>({
required: true,
message: '请输入计划竣工日期',
trigger: ['blur']
},
{
validator: chekcDate1,
trigger: ['blur']
}],
contract_content: [{
required: true,

View File

@ -165,8 +165,12 @@
</el-table-column>
<el-table-column label="结束日期" prop="end_date" width="220px">
<template #default="{ row }">
<el-form-item label-width="0">
<template #default="{ row, $index }">
<el-form-item label-width="0" :prop="`task_detail[${$index}].end_date`" :rules="{
validator: checkDate,
trigger: ['blur']
}
">
<el-date-picker v-model="row.end_date" clearable type="date" value-format="YYYY-MM-DD"
placeholder="请选择日期">
</el-date-picker>
@ -212,9 +216,13 @@
</el-form-item>
</template>
</el-table-column>
<el-table-column label="联系电话" prop="contact_phone" width="200px">
<template #default="{ row }">
<el-form-item label-width="0" prop="contact_phone">
<el-table-column label="联系电话" width="200px">
<template #default="{ row, $index }">
<el-form-item label-width="0" :prop="`task_detail[${$index}].contact_phone`" :rules="{
validator: checkPhone,
trigger: ['blur']
}
">
<el-input v-model="row.contact_phone" v-type="'phone'" />
</el-form-item>
@ -354,15 +362,26 @@ const submituser = (e: any) => {
showDialog3.value = false
}
const checkDate = (rule: any, value: any, callback: any, source) => {
const regex = /\[(\d+)\]/; // ,table
let index = 0
for (let key in source) {
index = key.match(regex)[1]
}
new Date(value) < new Date(formData.task_detail[index].start_date)
? callback(new Error('结束日期不能早于开始日期'))
: callback()
}
//
const formRules = reactive<any>({
contact_phone: [
{
validator: checkPhone,
trigger: ["blur"],
},
],
})

View File

@ -1,7 +1,6 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="80%" @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="160px" :rules="formRules">
<el-row>
<el-col :span="8">
@ -71,23 +70,21 @@
<el-col :span="8">
<el-form-item label="审核流程" prop="examine">
<el-select class="flex-1" v-model="formData.examine" clearable placeholder="请选择审核流程">
<el-option v-for="(item, index) in dictData.review_process " :key="index"
:label="item.name" :value="parseInt(item.value)" />
<el-option v-for="(item, index) in dictData.review_process " :key="index" :label="item.name"
:value="parseInt(item.value)" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="一级审核人" prop="one">
<el-input v-model="formData.one" clearable placeholder="请输入一级审核人"
@click="userclick('one')" />
<el-input v-model="formData.one" clearable placeholder="请输入一级审核人" @click="userclick('one')" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="二级审核人" prop="two">
<el-input v-model="formData.two" clearable placeholder="请输入二级审核人"
@click="userclick('two')" />
<el-input v-model="formData.two" clearable placeholder="请输入二级审核人" @click="userclick('two')" />
</el-form-item>
</el-col>
<el-col :span="8">
@ -148,8 +145,8 @@
<el-col :span="8">
<el-form-item label="造价依据" prop="according">
<el-select class="flex-1" v-model="formData.according" clearable placeholder="请选择造价依据">
<el-option v-for="(item, index) in dictData.cost_sentence " :key="index"
:label="item.name" :value="parseInt(item.value)" />
<el-option v-for="(item, index) in dictData.cost_sentence " :key="index" :label="item.name"
:value="parseInt(item.value)" />
</el-select>
</el-form-item>
</el-col>
@ -351,9 +348,41 @@ const customEvent = (e) => {
showDialog.value = false
}
const chekcDate = (rule: any, value: any, callback: any) => {
if (new Date(formData.kaigong) < new Date(formData.apptime)) {
callback(new Error('开工日期不能早于登记日期'))
} else {
callback()
}
}
const chekcDate1 = (rule: any, value: any, callback: any) => {
if (new Date(formData.jungong) < new Date(formData.apptime)) {
callback(new Error('竣工日期不能早于登记日期'))
}
else if (new Date(formData.jungong) < new Date(formData.kaigong)) {
callback(new Error('竣工日期不能早于开工日期'))
}
else {
callback()
}
}
//
const formRules = reactive<any>({
kaigong: [
{
validator: chekcDate,
trigger: ['blur']
}],
jungong: [
{
validator: chekcDate1,
trigger: ['blur']
}],
})