You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

545 lines
18 KiB
Vue

<template>
<div class="business-coop-management">
<!-- Search input -->
<!-- <div class="search-container">
<a-input-search v-model:value="searchKeyword" placeholder="请输入关键字" style="width: 320px" @search="getTable" @change="handleChangeSearch" allowClear />
</div> -->
<div class="header-container">
<div class="left-container">
<a-input-search v-model:value="searchKeyword" placeholder="请输入关键字" style="width: 320px" @search="getTable" @change="handleChangeSearch" allowClear />
</div>
<a-radio-group v-model:value="activeTab" style="margin-left: 16px">
<a-radio-button value="all" style="width: 80px; text-align: center">全部</a-radio-button>
<a-radio-button value="pending" style="width: 80px; text-align: center">待审核</a-radio-button>
<a-radio-button value="approved" style="width: 80px; text-align: center">已审核</a-radio-button>
</a-radio-group>
</div>
<!-- Business coop table -->
<a-table :columns="columns" :data-source="businessCoopList" :scroll="{ x: 1200, y: tableHeight }" :pagination="false" :loading="loading" @change="handleTableChange" rowKey="id">
<!-- Serial number column -->
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'serialNumber'">
<div>
{{ index + 1 }}
</div>
</template>
<!-- 单位名称 -->
<template v-else-if="column.dataIndex === 'companyName'">
{{ record.companyName || "-" }}
</template>
<!-- 姓名 -->
<template v-else-if="column.dataIndex === 'userName'">
{{ record.userName || "-" }}
</template>
<!-- 手机号 -->
<template v-else-if="column.dataIndex === 'tel'">
{{ record.tel || "-" }}
</template>
<!-- 来源 -->
<template v-else-if="column.dataIndex === 'recordType'">
{{ coopTypeMap[record.recordType] || "-" }}
</template>
<!-- 地址 -->
<template v-else-if="column.dataIndex === 'address'">
{{ record.address || "-" }}
</template>
<!-- 营业执照 -->
<template v-if="column.dataIndex === 'businessLicensePic'">
<a-image :src="record.businessLicensePic || defaultImage" class="image-cell" alt="Business License" />
</template>
<!-- 门头照片 -->
<template v-if="column.dataIndex === 'companyPic'">
<a-image :src="record.companyPic || defaultImage" class="image-cell" alt="Storefront Photo" />
</template>
<!-- 备注 -->
<template v-else-if="column.dataIndex === 'desp'">
{{ record.desp || "-" }}
</template>
<!-- Operation column -->
<!-- <template v-if="column.dataIndex === 'operate'">
<a href="javascript:" @click="showExamineModal(record)">审核</a>
</template> -->
<template v-if="column.dataIndex === 'operate'">
<span v-if="record.finished === 1" style="color: #999; cursor: not-allowed;">已审核</span>
<a v-else href="javascript:" @click="showExamineModal(record)">审核</a>
</template>
</template>
</a-table>
<!-- Pagination -->
<div class="g_pb_16 g_pt_16 g_pageBottom" v-if="businessCoopList.length > 0">
<a-pagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :pageSize="pagination.pageSize" :show-total="(total) => `共 ${total} 条`" @change="handlePageChange" :showSizeChanger="true" :show-quick-jumper="pagination.count < businessCoopList.length ? false : true" :hideOnSinglePage="false" />
</div>
<!-- Examine modal -->
<a-modal :visible="entryShowExamine" wrapClassName="zindex1001" :bodyStyle="{ height: '70vh', overflow: 'auto' }" :title="modalTitle" ok-text="确认" width="800px" dialogClass="mmpp" cancel-text="取消" @ok="entryClickExamine" @cancel="entryShowExamine = false" destroyOnClose :confirmLoading="entryShowExamineLoading">
<a-form :selfUpdate="true" :form="entryFormExamine" :label-col="formItemLayout1.labelCol" :wrapper-col="formItemLayout1.wrapperCol">
<a-form-item :label-col="formItemLayout1.labelCol" :wrapper-col="formItemLayout1.wrapperCol" label="企业名称">
<a-input v-model:value="formState.agencyName" autocomplete="off" placeholder="请输入企业名称" />
</a-form-item>
<a-form-item :label-col="formItemLayout1.labelCol" :wrapper-col="formItemLayout1.wrapperCol" label="联系人">
<a-input v-model:value="formState.userName" autocomplete="off" placeholder="请输入联系人" />
</a-form-item>
<a-form-item :label-col="formItemLayout1.labelCol" :wrapper-col="formItemLayout1.wrapperCol" label="手机号:">
<a-input v-model:value="formState.tel" autocomplete="off" placeholder="请输入手机号" />
</a-form-item>
<a-form-item label="菜单模板">
<a-select :showArrow="true" disabled :allowClear="true" style="width: 100%" @change="handleChange" placeholder="请选择菜单模板" v-model:value="formState.menuGroupIds">
<a-select-option :value="item.value" v-for="(item, index) in templateList" :key="index">{{ item.text }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label-col="formItemLayout1.labelCol" :wrapper-col="formItemLayout1.wrapperCol" label="门店数量">
<a-input-number disabled :precision="0" :min="0" style="width: 100%" :max="100000" v-model:value="formState.shopNum" autocomplete="off" placeholder="请输入门店数量" />
</a-form-item>
<a-form-item :label-col="formItemLayout1.labelCol" :wrapper-col="formItemLayout1.wrapperCol" label="企业地址">
<div class="display-flex">
<span style="max-width: 475px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis">{{ formState.address }}</span>
<span class="iconfont icon-dizhi f14" style="color: #999; line-height: 32px; margin-left: 6px; cursor: pointer" v-if="!formState.address" @click="handleOpenMap('address')"></span>
<span class="iconfont icon-dizhi f14" v-if="formState.address" style="color: #1890ff; line-height: 32px; margin-left: 6px; cursor: pointer" @click="handleOpenMap('address')"></span>
</div>
</a-form-item>
<a-form-item :label-col="formItemLayout1.labelCol" :wrapper-col="formItemLayout1.wrapperCol" label="客户标签">
<a-checkbox-group disabled :options="plainOptions" v-model:value="formState.channelItemType" style="width: 100%"> </a-checkbox-group>
</a-form-item>
<a-form-item :label-col="formItemLayout1.labelCol" :wrapper-col="formItemLayout1.wrapperCol" label="客户类型">
<a-radio-group disabled v-model:value="formState.classify">
<a-radio value="1"> 普通商家 </a-radio>
<a-radio value="2"> 行业商家 </a-radio>
<a-radio value="3"> 服务商 </a-radio>
<a-radio value="4"> 一般用户 </a-radio>
</a-radio-group>
</a-form-item>
<a-form-item :label-col="formItemLayout1.labelCol" :wrapper-col="formItemLayout1.wrapperCol" label="客户经理">
<a-select :allowClear="true" style="width: 100%" placeholder="请选择客户经理" v-model:value="formState.pmdUserId">
<a-select-option :value="item.value" v-for="(item, index) in pmdUserArray" :key="index">{{ item.text }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label-col="formItemLayout1.labelCol" :wrapper-col="formItemLayout1.wrapperCol" label="询单客服">
<a-select mode="multiple" :showArrow="true" :allowClear="true" style="width: 100%" placeholder="请选择询单客服" v-model:value="formState.consultUserIds">
<a-select-option :value="item.value" v-for="(item, index) in consultUsersArrModal" :key="index">{{ item.text }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label-col="formItemLayout1.labelCol" :wrapper-col="formItemLayout1.wrapperCol" label="客户拓展">
<a-select :allowClear="true" style="width: 100%" placeholder="请选择客户拓展" v-model:value="formState.channelExpansiontId">
<a-select-option :value="item.value" v-for="(item, index) in channelExpansiontArrayNew" :key="index">{{ item.text }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label-col="formItemLayout1.labelCol" :wrapper-col="formItemLayout1.wrapperCol" label="备注">
<a-textarea v-model:value="formState.desp" placeholder="请输入备注" :auto-size="{ minRows: 3, maxRows: 5 }" />
</a-form-item>
</a-form>
</a-modal>
<!-- Image view modal -->
<a-modal :visible="imageModalVisible" title="查看图片" @ok="imageModalVisible = false" @cancel="imageModalVisible = false">
<img :src="currentImage" alt="Image" style="max-width: 100%; max-height: 80vh" />
</a-modal>
<!-- 高德POI搜索 -->
<a-modal v-model:open="poiModal.isShow" title="位置" width="800px" :zIndex="1001" centered :footer="false" :destroyOnClose="true" :forceRender="true">
<div class style="height: calc(100vh - 200px); overflow-y: auto">
<mapPOIpanel :info="poiModal" @submitEvent="getPoiInfo" />
</div>
</a-modal>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, watch, getCurrentInstance } from "vue";
import { message } from "ant-design-vue";
import mapPOIpanel from "../components/poi.vue"; // 地图插件
import { getBusinessCoopList, addAgency, getTemplateList, getChannelUserList } from "@/api/bussinessCoop";
const commonJS = getCurrentInstance().appContext.app.config.globalProperties.G;
// State
const searchKeyword = ref("");
const loading = ref(false);
const businessCoopList = ref([]);
const pagination = reactive({
current: 1,
pageSize: 10,
total: 0,
showSizeChanger: true,
showTotal: (total) => `${total}`,
});
const defaultImage = "http://matripe.oss-cn-beijing.aliyuncs.com/defaultMountain.png";
// Search form
const searchForm = reactive({
pageNum: 1,
pageSize: 10,
keyword: "",
status: "", // 新增字段
});
const coopTypesArray = [
{ id: 1, name: "招人", value: "1", text: "招人" },
{ id: 2, name: "送人", value: "2", text: "送人" },
{ id: 3, name: "配套资源", value: "3", text: "配套资源" },
];
const coopTypeMap = Object.fromEntries(coopTypesArray.map((item) => [item.value, item.text]));
// Table columns
const columns = [
{ title: "序号", dataIndex: "serialNumber", width: 60 },
{ title: "单位名称", dataIndex: "companyName", ellipsis: true, width: 200 },
{ title: "姓名", dataIndex: "userName", ellipsis: true, width: 120 },
{ title: "手机号", dataIndex: "tel", width: 140 },
{ title: "来源", dataIndex: "recordType", width: 80 },
{ title: "地址", dataIndex: "address", ellipsis: true, width: 200 },
{ title: "营业执照", dataIndex: "businessLicensePic", width: 90 },
{ title: "门头照片", dataIndex: "companyPic", width: 90 },
{ title: "备注", dataIndex: "desp", ellipsis: true },
{ title: "创建时间", dataIndex: "createTime", width: 180 },
{ title: "操作", dataIndex: "operate", width: 80 },
];
// Examine modal state
const entryShowExamine = ref(false);
const entryShowExamineLoading = ref(false);
const modalTitle = ref("审核信息");
const formState = reactive({
agencyName: "",
userName: "",
tel: "",
menuGroupIds: "",
shopNum: 1,
channelItemType: "2",
classify: "1",
pmdUserId: null,
consultUserIds: ["315767"],
channelExpansiontId: "315986",
address: "",
lngLatStr: "",
updateContactTime: 0,
desp: "",
businessCooperationId:'',
});
// Form item layout
const formItemLayout1 = reactive({
labelCol: { span: 6 },
wrapperCol: { span: 16 },
});
// Template list
const templateList = ref([]);
// Customer tag options
const plainOptions = [
{
label: "达人",
value: "1",
flag: false,
color: "pink",
},
{
label: "网招",
value: "3",
flag: false,
color: "blue",
},
{
label: "门店",
value: "2",
flag: false,
color: "purple",
},
{
label: "个人",
value: "0",
flag: false,
color: "orange",
},
{
label: "校园",
value: "4",
flag: false,
color: "green",
},
];
// Customer manager list
const pmdUserArray = ref([]);
// Inquiry customer service list
const consultUsersArrModal = [
{
text: "熊猫/黄乐",
value: "322221",
},
{
text: "芍药/客服小田",
value: "322023",
},
{
text: "张南",
value: "315128",
},
{
text: "赵林",
value: "315767",
},
];
// Customer expansion list
const channelExpansiontArrayNew = [
{
text: "老王/王涵光",
value: "315986",
},
];
// Image view modal state
const imageModalVisible = ref(false);
const currentImage = ref("");
const tableHeight = ref(552);
window.addEventListener("resize", () => {
tableHeight.value = window.innerHeight - 381;
});
const fetchBusinessCoopList = async () => {
loading.value = true;
try {
const response = await getBusinessCoopList(searchForm);
if (response.status == 200) {
// const { recordList, recordCount } = response.data.pageBean;
// businessCoopList.value = response.data.recordList;
const formatList = response.data.recordList.map((item) => ({
...item,
createTime: commonJS.getPointTime(item.createTime, "YY--MM--DD HH:MM"),
}));
businessCoopList.value = formatList;
pagination.total = response.data.recordCount;
}
} catch (error) {
console.error("Failed to fetch business coop list:", error);
message.error("获取合作列表失败");
} finally {
loading.value = false;
}
};
// Methods
const getTable = async () => {
searchForm.keyword = searchKeyword.value;
searchForm.pageNum = 1;
pagination.current = 1;
// 同步 activeTab 的值到 status
if (activeTab.value === "all") {
searchForm.status = "";
} else if (activeTab.value === "pending") {
searchForm.status = 2;
} else if (activeTab.value === "approved") {
searchForm.status = 1;
}
await fetchBusinessCoopList();
};
const handleChangeSearch = () => {
searchForm.keyword = searchKeyword.value;
};
const activeTab = ref("all");
// 根据 activeTab 设置 status 参数
watch(
() => activeTab.value,
(newVal) => {
if (newVal === "all") {
searchForm.status = ""; // 全部不传参
} else if (newVal === "pending") {
searchForm.status = 2;
} else if (newVal === "approved") {
searchForm.status = 1;
}
fetchBusinessCoopList(); // 切换时重新获取数据
},
{ immediate: true }
);
const handleTableChange = (pag) => {
pagination.current = pag.current;
searchForm.pageNum = pag.current;
fetchBusinessCoopList();
};
const handlePageChange = (page) => {
pagination.current = page;
searchForm.pageNum = page;
fetchBusinessCoopList();
};
const showExamineModal = (record) => {
console.log(record);
// Pre-fill form data if needed
formState.agencyName = record.companyName || "";
formState.userName = record.userName || "";
formState.tel = record.tel || "";
formState.address = record.address || "";
formState.businessCooperationId = record.id || "";
entryShowExamine.value = true;
submitForm.value.address = record.address || "";
submitForm.value.lat = record.lat || "";
submitForm.value.lng = record.lng || "";
formState.lngLatStr = record.lng+','+record.lat;
};
const entryClickExamine = async () => {
// 将 consultUserIds 数组转为逗号分隔的字符串
const consultUserIdsStr = formState.consultUserIds.join(",");
// 构造最终提交的数据
const submitData = {
...formState,
consultUserIds: consultUserIdsStr,
};
entryShowExamineLoading.value = true;
try {
// await addAgency(formState);
await addAgency(submitData);
message.success("审核提交成功");
entryShowExamine.value = false;
fetchBusinessCoopList();
} catch (error) {
console.error("审核提交失败:", error);
message.error("审核提交失败");
} finally {
entryShowExamineLoading.value = false;
}
};
const showImageModal = (imageUrl) => {
currentImage.value = imageUrl;
imageModalVisible.value = true;
};
/* #################### 高德POI弹窗模块 #################### */
const poiModal = ref({
isShow: false,
name: "",
address: "",
lat: "",
lng: "",
type: "",
});
const submitForm = ref({});
const handleOpenMap = ($type) => {
// 打开地图弹窗
poiModal.value = {
isShow: true,
// name: submitForm.value.aliasName,
address: submitForm.value.address,
lat: commonJS.isNotEmptyCheck(submitForm.value.lat) ? submitForm.value.lat : 0,
lng: commonJS.isNotEmptyCheck(submitForm.value.lng) ? submitForm.value.lng : 0,
type: $type,
};
console.log("poiModal.value", poiModal.value);
};
const getPoiInfo = (e) => {
console.log("获取地图选择信息:", e, " -- 类型:", poiModal.value.type);
// 关闭弹窗
poiModal.value.isShow = false;
// 赋值
var reg = /.+?(省|市|自治区|自治州|县|区)/g; // 省市区的正则
if (poiModal.value.type == "address") {
submitForm.value.address = e.pointInfo.address;
submitForm.value.district = e.initInfo.district
.match(reg)
.filter((item, index) => item)
.join(",");
submitForm.value.lat = e.initInfo.lat;
submitForm.value.lng = e.initInfo.lng;
submitForm.value.mdistrict = e.initInfo.mdistrict;
formState.address = e.pointInfo.address;
formState.lngLatStr = e.initInfo.lng+','+e.initInfo.lat;
}
console.log(submitForm.value);
};
const handleChange = () => {
// Implement change logic here
};
// Fetch template list and customer manager list on mount
onMounted(async () => {
try {
const templateResponse = await getTemplateList();
templateList.value = templateResponse.data.map((item) => ({
text: item.groupName,
value: item.id + "",
}));
// 默认选择 id=2 的菜单模板
formState.menuGroupIds = "2";
const channelUserResponse = await getChannelUserList();
pmdUserArray.value = channelUserResponse.data.map((item) => ({
text: item.userName,
value: item.userId + "",
}));
formState.pmdUserId = "315767";
await fetchBusinessCoopList();
} catch (error) {
console.error("Failed to fetch template list or channel user list:", error);
message.error("获取模板列表或客户经理列表失败");
}
});
</script>
<style scoped>
.business-coop-management {
padding-top: 16px;
}
.search-container {
margin-bottom: 16px;
}
:deep(.ant-form-item) {
margin-bottom: 12px;
}
:deep(.image-cell) {
width: 48px;
height: 48px;
object-fit: cover;
border-radius: 4px;
cursor: pointer;
}
.header-container {
display: flex;
/* justify-content: space-between; */
align-items: center;
margin-bottom: 16px;
}
.left-container {
display: flex;
align-items: center;
}
</style>