applyManage.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. <template>
  2. <div class="container-apply">
  3. <!-- 头部el-card -->
  4. <div class="top-wrap" style="margin-bottom: 20px">
  5. <div class="top-card-box">
  6. <div class="tabs-box">
  7. <span v-for="(item, index) in listTitle" :key="item.ChartPermissionId" @click="tabsBoxBtn(item, index)" :class="item.ChartPermissionId == tabsPitchonType ? 'pitch' : ''">{{
  8. item.PermissionName
  9. }}</span>
  10. </div>
  11. <div>
  12. <el-input v-model="titleValue" style="width: 521px" placeholder="请输入活动名称" clearable>
  13. <i slot="prefix" class="el-input__icon el-icon-search"></i>
  14. </el-input>
  15. </div>
  16. </div>
  17. </div>
  18. <!-- 内容el-card -->
  19. <el-card>
  20. <!-- 选择部分 -->
  21. <div class="screen-box">
  22. <div class="screen-button">
  23. <template v-if="tabsPitchonType !== 3">
  24. <el-button type="primary" v-if="tabsSelectionOne && tabsPitchonType !== 4" @click="addOutbound(tabsBtnName)">{{ tabsBtnName }}</el-button>
  25. <el-button v-if="tabsPitchonType !== 1" type="primary" @click="addapply">新增报名</el-button>
  26. </template>
  27. <!-- 公司调研下的单独按钮 -->
  28. <template v-if="tabsPitchonType === 3">
  29. <!-- <el-tooltip class="item" effect="dark" content="不限人数的公司调研电话会请点此" placement="bottom">
  30. <el-button type="primary" v-if="tabsSelectionOne" @click="addOutbound('新增外呼人员')">新增外呼人员</el-button>
  31. </el-tooltip> -->
  32. <el-tooltip class="item" effect="dark" content="公司线下调研、限制人数的公司调研电话会请点此" placement="bottom">
  33. <el-button v-if="tabsPitchonType !== 1" type="primary" @click="addapply">新增报名</el-button>
  34. </el-tooltip>
  35. </template>
  36. <el-button type="primary" @click="addOutbound('新增预约纪要')">新增预约纪要</el-button>
  37. <el-button type="primary" @click="sendMessage">发送模板消息</el-button>
  38. </div>
  39. <div>
  40. <el-select placeholder="行业" clearable v-model="industry" @change="conditionChange" style="margin-bottom: 20px" v-if="!isResearch">
  41. <el-option v-for="item in chartPermissionList" :label="item.PermissionName" :key="item.ChartPermissionId" :value="item.ChartPermissionId"></el-option>
  42. </el-select>
  43. <el-select placeholder="活动类型" clearable @focus="activityType" v-model="cactivityTypeVal" @change="conditionChange" style="margin-bottom: 20px">
  44. <el-option v-for="item in cactivityTypeList" :label="item.ActivityTypeName" :key="item.ActivityTypeId" :value="item.ActivityTypeId"></el-option>
  45. </el-select>
  46. <date-picker v-model="issueTime" type="date" range placeholder="活动时间" value-type="format" @change="conditionChange"> </date-picker>
  47. <el-select placeholder="活动状态" clearable v-model="cactivityStatus" @change="conditionChange" style="margin-bottom: 20px">
  48. <el-option v-for="item in statusSelect" :label="item.name" :key="item.value" :value="item.value"></el-option>
  49. </el-select>
  50. <el-select placeholder="发布状态" clearable v-model="publishStatus" @change="conditionChange" style="margin-bottom: 20px">
  51. <el-option v-for="item in publishSelect" :label="item.name" :key="item.value" :value="item.value"></el-option>
  52. </el-select>
  53. </div>
  54. </div>
  55. <!-- 表格部分 -->
  56. <el-table @selection-change="selectChange" :data="dataList" style="width: 100%; margin-top: 15px" border ref="multipleTable">
  57. <el-table-column type="selection" align="center" key="ActivityId"></el-table-column>
  58. <el-table-column v-for="item in tableApplyColums" :key="item.label" :label="item.label" :width="item.widthsty" :min-width="item.minwidthsty" align="center">
  59. <template #header>
  60. <span>{{ item.label }}</span>
  61. <el-tooltip
  62. :content="`总报名人数已满、单机构报名人数满2人、爽约次数超限,仍点击${item.label === '预约失败人数' ? '预约外呼' : '报名'}的客户`"
  63. placement="top-start"
  64. v-if="item.key === 'SignupFailPeopleNum'"
  65. >
  66. <i class="el-icon-info" />
  67. </el-tooltip>
  68. </template>
  69. <template slot-scope="{ row }">
  70. <div v-if="item.key == 'ReminderPeopleNum'">
  71. <span v-if="row.ReminderPeopleNum > 0" class="editsty" @click="particularsBtn('会议提醒人数', row.ActivityId)">{{ row.ReminderPeopleNum }}</span>
  72. <span v-else>--</span>
  73. </div>
  74. <div v-else-if="item.key == 'SignupFailPeopleNum'">
  75. <span v-if="row.SignupFailPeopleNum == 0">--</span>
  76. <span v-else class="editsty" @click="particularsBtn('报名失败详情', row.ActivityId)">{{ row.SignupFailPeopleNum }}</span>
  77. </div>
  78. <span v-else @click="handleRowClick(row, item.key)" :style="handleRowStyle(item.key, row)">{{ handleRowContent(row, item.key) }}</span>
  79. </template>
  80. </el-table-column>
  81. </el-table>
  82. <el-col :span="24" class="toolbar">
  83. <m-page :total="total" :page_no="page_no" :pageSize="10" @handleCurrentChange="handleCurrentChange" />
  84. </el-col>
  85. </el-card>
  86. <!-- 详情弹框 -->
  87. <atc-particulars :dialogVisible.sync="dialogVisible" :detailData.sync="detailData" />
  88. <!-- 新增外呼的弹框 -->
  89. <apply-dialog
  90. :addDialogVisible.sync="addDialogVisible"
  91. :dialogVisibleId="dialogVisibleId"
  92. :selectList="selectList"
  93. :signUpAdd="signUpAdd"
  94. :addDialogType="addDialogType"
  95. :tabsPitchonType="tabsPitchonType"
  96. :minimumSummation="minimumSummation"
  97. :selectionArr="selectionArr"
  98. />
  99. <!-- 报名详情弹框 -->
  100. <particulars-dialog :dialogVisibleId="dialogVisibleId" :particularsDialogVisible.sync="particularsDialogVisible" :subscribe="subscribe" />
  101. <generation-ask :generaitonType="generaitonType" :generaitondialogVisib.sync="generaitondialogVisib" :generaitonId="generaitonId" />
  102. <summary-remind :dialogVisibleId="dialogVisibleId" :summaryRemindDlg.sync="summaryRemindDlg" :subscribe="subscribe" />
  103. <template-message :messageDialog.sync="messageDialogVisible" :selectionArr="selectionArr" />
  104. </div>
  105. </template>
  106. <script>
  107. import { raiInterface } from "@/api/api.js";
  108. import mPage from "@/components/mPage.vue";
  109. import ApplyDialog from "../components/apply/applyDialog.vue";
  110. import ParticularsDialog from "../components/apply/particularsDialog.vue";
  111. import AtcParticulars from "../components/atcParticulars.vue";
  112. import GenerationAsk from "../components/generationAsk.vue";
  113. import SummaryRemind from "../components/apply/summaryRemind.vue";
  114. import { ListTitle, purchaserListTitle, TableApplyColums, StatusSelect, PublishSelect } from "../components/apply/applyTableColums";
  115. import TemplateMessage from "../components/apply/templateMessage.vue";
  116. export default {
  117. name: "",
  118. components: { ApplyDialog, ParticularsDialog, mPage, AtcParticulars, GenerationAsk, SummaryRemind, TemplateMessage },
  119. props: {},
  120. data() {
  121. return {
  122. tabsSelectionOne: true,
  123. dataList: [], //表格的列表
  124. page_no: sessionStorage.getItem("interviewListBack") ? JSON.parse(sessionStorage.getItem("interviewListBack")).page_no : 1,
  125. total: 0, //条数
  126. PageSize: 10, //每页显示几条
  127. industry: "", //行业
  128. cactivityTypeVal: "", //活动
  129. issueTime: "", //时间
  130. selectList: "", //新增外呼人员的id
  131. chartPermissionList: [], //行业的数组
  132. cactivityTypeList: [], //活动类型
  133. addDialogVisible: false, //新增外呼的弹框
  134. particularsDialogVisible: false, //报名详情弹框
  135. subscribe: "", //预约外呼弹框的tittle
  136. titleValue: "", //标题关键词
  137. tabsPitchonType: 1,
  138. dialogVisible: false, //文章详情
  139. detailData: {}, //文章详情数据
  140. dialogVisibleId: "", //弹框id
  141. reminder: false, //提示
  142. generaitondialogVisib: false, //代问的弹框
  143. generaitonId: "",
  144. generaitonType: "报名",
  145. numberFull: false, //
  146. tableApplyColums: [],
  147. signUpAdd: "",
  148. minimumSummation: "",
  149. numberLimi: false, //
  150. addDialogType: "新增外呼人员",
  151. summaryRemindDlg: false, //预约纪要、会议提醒
  152. isShowAppointment: true, //是 预约纪要、会议提醒
  153. activityTypeName: [],
  154. cactivityStatus: 1,
  155. publishStatus: "1", //发布状态
  156. messageDialogVisible: false, //发送消息模版
  157. isResearchPoints: false, //
  158. };
  159. },
  160. computed: {
  161. // 弘则 研选 是否是研选
  162. isResearch() {
  163. return this.$route.path.indexOf("purchaser") != -1 ? true : false;
  164. },
  165. listTitle() {
  166. return !this.isResearch ? ListTitle : purchaserListTitle;
  167. },
  168. statusSelect() {
  169. return StatusSelect;
  170. },
  171. publishSelect() {
  172. return PublishSelect;
  173. },
  174. tabsBtnName() {
  175. return this.tabsPitchonType == 1 ? "新增报名" : "新增外呼人员";
  176. },
  177. },
  178. watch: {
  179. titleValue() {
  180. this.page_no = 1;
  181. this.init();
  182. this.getsDataList();
  183. },
  184. },
  185. created() {},
  186. mounted() {
  187. this.tableApplyColums = TableApplyColums(1);
  188. !this.isResearch && this.chartPermission();
  189. this.getsDataList();
  190. },
  191. methods: {
  192. init() {
  193. this.issueTime = "";
  194. this.industry = "";
  195. this.cactivityTypeVal = "";
  196. },
  197. //头部tabs
  198. tabsBoxBtn(item, index) {
  199. this.tabsPitchonType = item.ChartPermissionId;
  200. this.tableApplyColums = TableApplyColums(item.ChartPermissionId);
  201. this.cactivityTypeVal = "";
  202. this.isResearchPoints = false;
  203. this.tabsSelectionOne = item.ChartPermissionId == 2 || item.ChartPermissionId == 5 ? false : true;
  204. this.page_no = 1;
  205. this.getsDataList();
  206. },
  207. //列表表格
  208. getsDataList() {
  209. raiInterface
  210. .activitySignup({
  211. CurrentIndex: this.page_no,
  212. PageSize: this.PageSize,
  213. StartDate: this.issueTime[0],
  214. EndDate: this.issueTime[1],
  215. KeyWord: this.titleValue,
  216. SearchType: this.tabsPitchonType,
  217. ChartPermissionId: this.industry,
  218. ActivityTypeId: this.cactivityTypeVal,
  219. ActiveState: this.cactivityStatus,
  220. PublishStatus: this.publishStatus ? Number(this.publishStatus) : 2,
  221. IsResearch: this.isResearch,
  222. })
  223. .then((res) => {
  224. if (res.Ret !== 200) return;
  225. this.dataList = res.Data.List;
  226. this.total = res.Data.Paging.Totals;
  227. });
  228. },
  229. //添加新增外呼人员
  230. addOutbound(type) {
  231. if (!this.selectList) {
  232. this.$message.warning("请先选择活动");
  233. } else if (this.tabsPitchonType == 1 && this.isGenre) {
  234. return this.$message.warning("活动类型不同,无法同时新增报名");
  235. } else {
  236. if (type == "新增外呼人员") {
  237. if (this.reminder && this.tabsPitchonType !== 1) return this.$message.warning("当前活动无法新增外呼人员");
  238. this.addDialogVisible = true;
  239. } else {
  240. if (!this.isShowAppointment && type === "新增预约纪要") return this.$message.error("该活动无法预约纪要");
  241. this.addDialogVisible = true;
  242. }
  243. this.addDialogType = type;
  244. }
  245. },
  246. //表格选择复选框的事件
  247. selectChange(selection, row) {
  248. const arr = [];
  249. const num = [];
  250. const summation = [];
  251. const genre = [];
  252. let minimum = [];
  253. let isResearch = [];
  254. this.selectionArr = selection;
  255. selection.forEach((item) => {
  256. arr.push(item.ActivityId);
  257. num.push(item.LimitPeopleNum);
  258. summation.push(item.SignupPeopleNum);
  259. genre.push(item.ActivityTypeName);
  260. isResearch.push(item.IsResearchPoints);
  261. minimum.push(item.LimitPeopleNum - item.SignupPeopleNum);
  262. });
  263. this.activityTypeName = genre;
  264. this.isShowAppointment = selection.every((item) => item.IsShowAppointment == true);
  265. const str = arr.join(",");
  266. this.reminder = num.some((item) => item > 0);
  267. this.selectList = str;
  268. this.isGenre = new Set(genre).size > 1 ? true : false;
  269. if (this.tabsPitchonType !== 1 && (selection[0] ? selection[0].LimitPeopleNum > 0 : true)) {
  270. num.forEach((item) => {
  271. this.numberFull = summation.some((key) => key >= item);
  272. });
  273. }
  274. if (this.tabsPitchonType !== 1) {
  275. console.log(isResearch, isResearch.length);
  276. this.tabsPitchonType == 3 && this.isResearchHandler(isResearch);
  277. this.minimumSummation = Math.min(...minimum);
  278. this.numberLimi = num.includes(0) && num.some((item) => item > 0);
  279. }
  280. },
  281. // 公司调研下的判断
  282. isResearchHandler(isResearch) {
  283. if (isResearch && isResearch.length > 1) {
  284. for (let i = 0; i < isResearch.length - 1; i++) {
  285. if (isResearch[i] !== isResearch[i + 1]) {
  286. this.isResearchPoints = true;
  287. break;
  288. }
  289. }
  290. } else {
  291. this.isResearchPoints = false;
  292. }
  293. },
  294. //报名详情的弹框
  295. particularsBtn(val, id) {
  296. this.dialogVisibleId = id;
  297. this.subscribe = val;
  298. if (val === "会议提醒人数" || val === "纪要预约人数") {
  299. this.summaryRemindDlg = true;
  300. } else {
  301. this.particularsDialogVisible = true;
  302. }
  303. },
  304. //change事件
  305. conditionChange() {
  306. this.page_no = 1;
  307. this.getsDataList();
  308. },
  309. //获取行业
  310. chartPermission() {
  311. raiInterface.chartPermission({ IsHideResearch: !this.isResearch }).then((res) => {
  312. if (res.Ret === 200) {
  313. this.chartPermissionList = res.Data.List;
  314. }
  315. });
  316. },
  317. //活动类型
  318. activityType() {
  319. raiInterface
  320. .activitySignuplistSearch({
  321. SearchType: this.tabsPitchonType,
  322. })
  323. .then((res) => {
  324. if (res.Ret === 200) {
  325. this.cactivityTypeList = res.Data.List;
  326. }
  327. });
  328. },
  329. //分页
  330. handleCurrentChange(page) {
  331. this.page_no = page;
  332. this.getsDataList();
  333. },
  334. //点击标题的弹框
  335. titleBtnClick(id) {
  336. raiInterface.activityDetail({ ActivityId: Number(id) }).then((res) => {
  337. if (res.Ret == 200) {
  338. this.detailData = res.Data;
  339. }
  340. });
  341. this.dialogVisible = true;
  342. },
  343. //点击代问的弹框
  344. inquireBtn(id) {
  345. this.generaitondialogVisib = true;
  346. this.generaitonId = id;
  347. },
  348. //新增报名
  349. addapply() {
  350. if (!this.selectList) {
  351. return this.$message.warning("请先选择活动");
  352. } else if (this.isGenre) {
  353. return this.$message.warning("活动类型不同,无法同时新增报名");
  354. } else if (this.isResearchPoints && this.tabsPitchonType == 3) {
  355. return this.$message.warning("所选活动无法同时新增报名");
  356. } else {
  357. if (this.numberLimi && this.tabsPitchonType !== 4) {
  358. return this.$message.warning("不限人数的电话会请新增外呼人员,限制人数的电话会请新增报名");
  359. } else if (this.numberFull && this.tabsPitchonType !== 4) {
  360. return this.$message.warning("新增失败,活动人数超限。");
  361. }
  362. this.signUpAdd = this.activityTypeName.includes("公司调研电话会(易董)") ? "易董" : this.tabsPitchonType == 4 ? "c类" : "报名";
  363. this.addDialogType = "新增报名";
  364. this.addDialogVisible = true;
  365. }
  366. },
  367. /* 表格行的样式 */
  368. handleRowStyle(key, row) {
  369. if (["ActivityName", "SignupPeopleNum", "AppointmentPeopleNum", "AskNum"].includes(key)) {
  370. return row.PublishStatus == 3 ? "cursor: pointer" : "color: #409eff; cursor: pointer";
  371. }
  372. return "";
  373. },
  374. /* 表格行的点击事件 */
  375. handleRowClick(row, key) {
  376. switch (key) {
  377. case "ActivityName":
  378. this.titleBtnClick(row.ActivityId);
  379. break;
  380. case "SignupPeopleNum":
  381. this.particularsBtn("报名详情", row.ActivityId);
  382. break;
  383. case "AppointmentPeopleNum":
  384. this.particularsBtn("纪要预约人数", row.ActivityId);
  385. break;
  386. case "AskNum":
  387. this.inquireBtn(row.ActivityId);
  388. break;
  389. default:
  390. "";
  391. }
  392. },
  393. /* 表格行的数据处理 */
  394. handleRowContent(row, key) {
  395. if (["LimitPeopleNum"].includes(key)) {
  396. return row[key] > 0 && !row.YidongActivityId ? row[key] : "--";
  397. } else if (key == "ActiveState") {
  398. let status = row[key] == 1 ? "未开始" : row[key] == 2 ? "进行中" : "已结束";
  399. return status;
  400. } else if (key == "PublishStatus") {
  401. let status = row["PublishStatus"] == 1 ? "已发布" : row["PublishStatus"] == 2 ? "未发布" : "已取消";
  402. return status;
  403. } else {
  404. return row[key];
  405. }
  406. },
  407. // 发送模版消息
  408. sendMessage() {
  409. if (this.selectList && this.selectList.split(",").length === 1) {
  410. this.messageDialogVisible = true;
  411. } else {
  412. this.$message.error("请选择一个活动");
  413. }
  414. },
  415. },
  416. };
  417. </script>
  418. <style scoped lang="scss">
  419. .container-apply {
  420. .top-wrap {
  421. margin-bottom: 28px;
  422. padding: 20px 30px 0;
  423. background: #fff;
  424. border: 1px solid #ececec;
  425. border-radius: 4px;
  426. box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
  427. }
  428. .top-card-box {
  429. display: flex;
  430. justify-content: space-between;
  431. .tabs-box {
  432. span {
  433. display: inline-block;
  434. padding: 9px 24px;
  435. background-color: #e9f4ff;
  436. border: 1px solid #b3d8ff;
  437. border-radius: 4px;
  438. margin-right: 30px;
  439. margin-bottom: 20px;
  440. color: #409eff;
  441. }
  442. .pitch {
  443. background-color: #409eff;
  444. border: none;
  445. color: #fff;
  446. }
  447. }
  448. }
  449. .screen-box {
  450. display: flex;
  451. :first-child {
  452. margin-right: 10px;
  453. }
  454. .el-select {
  455. margin-right: 25px;
  456. }
  457. }
  458. .mx-datepicker {
  459. width: 220px !important;
  460. margin-right: 25px;
  461. }
  462. .screen-button {
  463. display: flex;
  464. flex-wrap: wrap;
  465. .el-button {
  466. height: 40px;
  467. margin-right: 20px;
  468. margin-left: 0;
  469. }
  470. }
  471. }
  472. </style>