partner.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. <!-- 模板区域 -->
  2. <template>
  3. <div class="flex overflow-hidden">
  4. <!-- 右侧 -->
  5. <PageMain class="vh100 flex-1 overflow-hidden flex flex-col">
  6. <SearchForm :fields="fields" :formInline="formInline" :onSearch="findpage" :onReset="resetForm">
  7. </SearchForm>
  8. <div class="flex-1 overflow-auto">
  9. <ComplexTable :tableData="tableData" :columns="columns" :showIndex="false" :columnwidth="250"
  10. :showSelect="false" :pageInfo="pageInfo" @getList="getList">
  11. <template v-slot:table-title-btn>
  12. <el-button type="primary" @click="addPartner">
  13. 添加合伙人
  14. <template #icon>
  15. <el-icon>
  16. <Plus />
  17. </el-icon>
  18. </template>
  19. </el-button>
  20. </template>
  21. <template v-slot:operation="scope">
  22. <el-button type="primary" link @click="detailPartner(scope.operationData)">详情</el-button>
  23. <el-dropdown placement="bottom-start" trigger="click">
  24. <span class="el-dropdown-link">
  25. 更 多
  26. </span>
  27. <template #dropdown>
  28. <el-dropdown-menu>
  29. <el-dropdown-item @click="editPartner(scope.operationData)">编辑</el-dropdown-item>
  30. <el-dropdown-item @click="enablePartner(scope.operationData)">{{ scope.operationData.partStatus ? '禁用'
  31. : '启用' }}</el-dropdown-item>
  32. <el-dropdown-item @click="queryPartnerRelation(scope.operationData)">关系查询</el-dropdown-item>
  33. <el-dropdown-item @click="addNewGrade(scope.operationData)">添加新等级</el-dropdown-item>
  34. <el-dropdown-item @click="assignDayJudge(scope.operationData)">添加为业务员</el-dropdown-item>
  35. </el-dropdown-menu>
  36. </template>
  37. </el-dropdown>
  38. </template>
  39. <template v-slot:search="scope">
  40. {{ scope.slotData.label }}
  41. </template>
  42. </ComplexTable>
  43. </div>
  44. </PageMain>
  45. <el-dialog v-model="addPartnerShow" title="添加合伙人" width="1000">
  46. <addOperation ref="addOperationRef" @closeDialog="closeAddOperation"></addOperation>
  47. </el-dialog>
  48. <el-dialog v-model="addNewGradeShow" title="添加合伙人等级" width="1000">
  49. <el-checkbox-group v-model="checkList">
  50. <el-checkbox :disabled="item.grade <= gradeList[gradeList.length - 1]" :label="item.gradeName"
  51. :value="item.grade" v-for="item in userGradeList" :key="item.grade" />
  52. </el-checkbox-group>
  53. <template #footer>
  54. <div class="dialog-footer">
  55. <el-button @click="addNewGradeShow = false">取消</el-button>
  56. <el-button type="primary" @click="addNewGradeSave">
  57. 确定
  58. </el-button>
  59. </div>
  60. </template>
  61. </el-dialog>
  62. <el-dialog v-model="PartnerRelationShow" title="关系查询" width="1000">
  63. <el-table :data="relationQuery" style="width: 100%">
  64. <el-table-column prop="type" label="级别" width="100" align="center">
  65. <template #default="scope">
  66. {{ scope.row.type == 1 ? '一级' : scope.row.type == 2 ? '二级' : scope.row.type == 3 ? '三级' : scope.row.type ==
  67. 4 ? '四级' : scope.row.type == 5 ? '五级' : '-' }}
  68. </template>
  69. </el-table-column>
  70. <el-table-column prop="userId" label="工号" width="180" align="center" />
  71. <el-table-column prop="userName" label="姓名" align="center" />
  72. <el-table-column prop="suggestName" label="推荐人" align="center" />
  73. <el-table-column prop="deptName" label="部门" width="250" align="center" />
  74. <el-table-column prop="mobile" label="电话" align="center" />
  75. </el-table>
  76. </el-dialog>
  77. </div>
  78. </template>
  79. <!-- 行为区域 -->
  80. <script lang='ts' setup>
  81. import { ref, reactive, onBeforeMount } from 'vue'
  82. import addOperation from './modules/addPartner.vue'
  83. import api from '@/api'
  84. import { ElMessage, ElMessageBox } from 'element-plus';
  85. import router from '@/router';
  86. // 页面加载时获取机构列表
  87. onBeforeMount(() => {
  88. getInstitutionList();
  89. getGradeOptions();
  90. findpage();
  91. });
  92. interface PageInfo {
  93. pageNum: number;
  94. pageSize: number;
  95. sizes: number[];
  96. total: number;
  97. }
  98. // 机构树相关变量
  99. const addOperationRef = ref();//添加合伙人弹窗实例
  100. const userId = ref('');//用户id
  101. const addPartnerShow = ref(false);//添加合伙人弹窗显示状态
  102. const addNewGradeShow = ref(false);//添加新等级弹窗显示状态
  103. const PartnerRelationShow = ref(false);//关系查询弹窗显示状态
  104. const checkList = ref([]);//选中的等级列表
  105. const userGradeList = ref();//用户等级列表
  106. const gradeList = ref([]);//等级列表
  107. const relationQuery = ref([]);//关系查询数据
  108. const deptTreeData = ref<any[]>([]);//机构树数据
  109. const tableData = ref([]);//表格数据
  110. const formInline = reactive({
  111. name: '',//姓名
  112. mobile: "",//手机号
  113. userId: '',//工号
  114. grade: '',//合伙人等级
  115. inviter: "",//邀请人
  116. deptId: '',//机构id
  117. typeAttr: '',
  118. })
  119. const pageInfo = ref({
  120. pageNum: 1,
  121. pageSize: 20,
  122. sizes: [10, 20, 30, 40, 50],
  123. total: 0,
  124. });
  125. const typeAttrOptions = ref([
  126. {
  127. label: '个代',
  128. value: '6'
  129. },
  130. {
  131. label: '合伙人',
  132. value: '3'
  133. }
  134. ])
  135. const statusOptions = ref([
  136. {
  137. label: '待入职',
  138. value: '0'
  139. },
  140. {
  141. label: '入职待审核',
  142. value: '1'
  143. },
  144. {
  145. label: '审核不通过',
  146. value: '2'
  147. },
  148. {
  149. label: '已入职',
  150. value: '3'
  151. }
  152. ])
  153. const parentIdprops = {
  154. expandTrigger: 'hover' as const,
  155. value: 'id',
  156. label: 'name',
  157. checkStrictly: true,
  158. }
  159. //表格字段数据
  160. const fields = ref([
  161. { label: "合伙人", model: "name", type: "input", placeholder: "输入姓名手机号查找" },
  162. {
  163. label: "归属机构", model: "deptId", type: "cascader", options: deptTreeData, props: parentIdprops, onChange: (value: any) => {
  164. formInline.deptId = value[value.length - 1];
  165. }
  166. },
  167. {
  168. label: "类型", model: "typeAttr", type: "select", placeholder: "请选择类型", options: typeAttrOptions,
  169. },
  170. {
  171. label: "等级", model: "grade", type: "select", placeholder: "选择等级", options: userGradeList, props: {
  172. label: 'gradeName',
  173. value: 'grade',
  174. },
  175. },
  176. {
  177. label: "人员状态", model: "status", type: "select", placeholder: "请选择人员状态", options: statusOptions
  178. },
  179. {
  180. label: "账号状态", model: "isEnable", type: "select", placeholder: "请选择账号状态", options: [
  181. {
  182. label: '启用',
  183. value: '0'
  184. },
  185. {
  186. label: '禁用',
  187. value: '1'
  188. },
  189. ],
  190. },
  191. {
  192. label: "推荐人", model: "referrerName", type: "input", placeholder: "输入姓名手机号"
  193. },
  194. ]);
  195. const columns = [
  196. { prop: "name", label: "姓名", width: '200' },
  197. { prop: "mobile", label: "手机号", width: '200' },
  198. {
  199. prop: "typeAttr", label: "类型", width: '200',
  200. formatter: (row: any) => {
  201. const map: any = {
  202. '6': '个代',
  203. '7': '渠道',
  204. '5': '团队',
  205. '8': '电销组',
  206. '3': '合伙人',
  207. }
  208. return row.typeAttr?.split(',')
  209. .map((typeId: any) => map[typeId] || typeId)
  210. .join(',') || '未知'
  211. }
  212. },
  213. {
  214. prop: "grade", label: "等级", width: '200',
  215. formatter: (row: any) => {
  216. return row.grade
  217. .split(',')
  218. .map((gradeId: any) => userGradeList.value.find((item: any) => item.grade == gradeId)?.gradeName || gradeId)
  219. .join(',') || '未知';
  220. }
  221. },
  222. {
  223. prop: "deptName", label: "所属机构", width: '200'
  224. },
  225. { prop: "premium", label: "累计保费", width: '200' },
  226. { prop: "kickback", label: "累计佣金", width: '200' },
  227. { prop: "createTime", label: "创建时间", width: '200' },
  228. {
  229. prop: "status", label: "人员状态", width: '200',
  230. formatter: (row: any) => {
  231. return statusOptions.value.find((item: any) => item.value == row.status)?.label || row.status;
  232. }
  233. },
  234. {
  235. prop: "partStatus", label: "账号状态", width: '200',
  236. formatter: (row: any) => {
  237. return row.partStatus ? '启用' : '禁用';
  238. }
  239. },
  240. {
  241. prop: "leaderIdName", label: "管理人", width: '200',
  242. },
  243. {
  244. prop: "referrerName", label: "推荐人", width: '200',
  245. },
  246. ];
  247. // 添加合伙人
  248. const addPartner = () => {
  249. console.log('添加合伙人');
  250. addPartnerShow.value = true;
  251. }
  252. // 详情合伙人
  253. const detailPartner = (item: any) => {
  254. router.push({
  255. path: '/PartnerManagement/partnerDetail',
  256. query: {
  257. userId: item.userId,
  258. }
  259. })
  260. }
  261. // 编辑合伙人
  262. const editPartner = (item: any) => {
  263. console.log('编辑合伙人:', item);
  264. addPartnerShow.value = true
  265. nextTick(() => {
  266. addOperationRef.value.initEditData(item.userId)
  267. })
  268. }
  269. const enablePartner = (item: any) => {
  270. console.log('启用合伙人:', item);
  271. if (item.partStatus) {
  272. ElMessageBox.confirm(
  273. '确定要禁用该合伙人账号吗?',
  274. '禁用',
  275. {
  276. confirmButtonText: '确定禁用',
  277. type: 'warning',
  278. center: true,
  279. confirmButtonClass: 'el-button--primary',
  280. }
  281. )
  282. .then(() => {
  283. api.partnerApi.enableDisable(item.userId, '0').then((res: any) => {
  284. if (res.code == '200') {
  285. ElMessage({
  286. type: 'success',
  287. message: res.msg,
  288. plain: true,
  289. })
  290. findpage();
  291. } else {
  292. ElMessage.error(res.msg || '禁用失败');
  293. }
  294. })
  295. })
  296. .catch(() => {
  297. })
  298. } else {
  299. api.partnerApi.enableDisable(item.userId, '1').then((res: any) => {
  300. if (res.code == '200') {
  301. ElMessage({
  302. type: 'success',
  303. message: res.msg,
  304. plain: true,
  305. })
  306. findpage();
  307. } else {
  308. ElMessage.error(res.msg || '启用失败');
  309. }
  310. })
  311. }
  312. }
  313. // 关系查询
  314. const queryPartnerRelation = (item: any) => {
  315. api.partnerApi.relationalQuery(item.userId).then((res: any) => {
  316. if (res.code == '200') {
  317. relationQuery.value = res.data;
  318. PartnerRelationShow.value = true;
  319. } else {
  320. ElMessage.error(res.msg || '关系查询失败');
  321. }
  322. })
  323. }
  324. // 添加新等级
  325. const addNewGrade = (item: any) => {
  326. userId.value = item.userId;
  327. api.partnerApi.queryGrade(item.userId).then((res: any) => {
  328. if (res.code == '200') {
  329. gradeList.value = res.data;
  330. addNewGradeShow.value = true;
  331. } else {
  332. ElMessage.error(res.msg);
  333. }
  334. })
  335. }
  336. // 添加新等级保存
  337. const addNewGradeSave = () => {
  338. api.partnerApi.addNewGrade({
  339. userId: userId.value,
  340. gradeList: checkList.value
  341. }).then((res: any) => {
  342. if (res.code == '200') {
  343. ElMessage({
  344. type: 'success',
  345. message: res.msg,
  346. plain: true,
  347. })
  348. checkList.value = []
  349. addNewGradeShow.value = false;
  350. findpage();
  351. }
  352. })
  353. }
  354. // 添加业务员
  355. const assignDayJudge = (item: any) => {
  356. console.log('添加业务员:', item.userId);
  357. api.partnerApi.partnerAddsSalesperson(item.userId).then((res: any) => {
  358. if (res.code == '200') {
  359. ElMessage({
  360. type: 'success',
  361. message: res.msg,
  362. plain: true,
  363. })
  364. findpage();
  365. } else {
  366. }
  367. })
  368. }
  369. //分页事件
  370. function getList(item: PageInfo) {
  371. pageInfo.value.pageNum = item.pageNum;
  372. pageInfo.value.pageSize = item.pageSize;
  373. findpage();
  374. };
  375. const resetForm = () => {
  376. Object.assign(formInline, {
  377. name: '',//姓名
  378. mobile: "",//手机号
  379. userId: '',//工号
  380. grade: '',//合伙人等级
  381. inviter: "",//邀请人
  382. deptId: '',//机构id
  383. typeAttr: '',
  384. })
  385. findpage();
  386. }
  387. //数据查询
  388. function findpage() {
  389. let query = { ...formInline }
  390. api.partnerApi.partnerQueryPage({ pages: pageInfo.value.pageNum, size: pageInfo.value.pageSize, ...query }).then((res: any) => {
  391. if (res.code == '200') {
  392. tableData.value = res.data.records;
  393. pageInfo.value.pageNum = res.data.current;
  394. pageInfo.value.pageSize = res.data.size;
  395. pageInfo.value.total = res.data.total;
  396. } else {
  397. }
  398. });
  399. }
  400. // 获取机构列表
  401. const getInstitutionList = () => {
  402. api.institutionApi.institutionList({}).then((res: any) => {
  403. if (res.code === 200) {
  404. deptTreeData.value = res.data;
  405. }
  406. });
  407. };
  408. // 获取人员等级列表
  409. const getGradeOptions = () => {
  410. api.partnerApi.queryGradeName().then((res: any) => {
  411. if (res.code === 200) {
  412. userGradeList.value = res.data;
  413. console.log(userGradeList.value);
  414. }
  415. })
  416. }
  417. const closeAddOperation = (text: string) => {
  418. if (text == '确定') {
  419. findpage();
  420. }
  421. addPartnerShow.value = false
  422. }
  423. </script>
  424. <!-- 样式区域 -->
  425. <style lang='scss' scoped>
  426. .custom-tree-node {
  427. flex: 1;
  428. display: flex;
  429. align-items: center;
  430. justify-content: space-between;
  431. font-size: 14px;
  432. padding-right: 8px;
  433. }
  434. :deep(.el-dropdown-link) {
  435. cursor: pointer;
  436. color: var(--el-color-primary);
  437. display: flex;
  438. align-items: center;
  439. margin-left: 15px;
  440. }
  441. </style>