index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. <!-- 运营管理 多频多台 -->
  2. <template>
  3. <div class="app-container">
  4. <el-button
  5. type="primary"
  6. icon="el-icon-plus"
  7. size="mini"
  8. @click="getDialog()"
  9. v-hasPermi="['operation:channels:add']"
  10. >新增多频多台</el-button
  11. >
  12. <el-table :data="tableData" v-loading="loading">
  13. <el-table-column label="频道名称" align="center" prop="name" />
  14. <el-table-column label="设备" align="center">
  15. <template slot-scope="scope">
  16. <span
  17. v-for="(item, index) in scope.row.deviceList"
  18. :key="item.clientTypeId"
  19. >
  20. <span>{{ item.name }}</span>
  21. <span v-show="index + 1 !== scope.row.deviceList.length">,</span>
  22. </span>
  23. </template>
  24. </el-table-column>
  25. <!-- <el-table-column label="序号" align="center" prop="sort" /> -->
  26. <!-- <el-table-column label="序号" align="center">
  27. <template slot-scope="scope">
  28. <div v-if="editData.currentEditIndex !== scope.$index">
  29. <span style="margin-right: 8px">
  30. {{ scope.row.indexNum }}
  31. </span>
  32. <svg-icon
  33. icon-class="edit"
  34. @click.native="handleEditClick(scope.row, scope.$index)"
  35. />
  36. </div>
  37. <el-input
  38. v-else
  39. v-model="scope.row.indexNum"
  40. size="mini"
  41. style="width: 60px"
  42. type="number"
  43. @blur="onNumberBlur(scope.row, scope.$index)"
  44. @keyup.enter.native="onNumberBlurEnter(scope.row, scope.$index)"
  45. placeholder="序号"
  46. ref="numberInput"
  47. />
  48. </template>
  49. </el-table-column> -->
  50. <!-- <el-table-column label="序号" align="center">
  51. <template slot-scope="scope">
  52. <el-button type="text">{{ scope.row.sort }}</el-button>
  53. <el-button type="text" icon="el-icon-edit" />
  54. </template>
  55. </el-table-column> -->
  56. <el-table-column label="操作" align="center">
  57. <template slot-scope="scope">
  58. <el-button type="text" @click="getDialog(scope.row, true)"
  59. >查看</el-button
  60. >
  61. <el-button
  62. type="text"
  63. @click="getDialog(scope.row)"
  64. v-hasPermi="['operation:channels:edit']"
  65. >编辑</el-button
  66. >
  67. <el-button
  68. type="delete"
  69. @click="getRemove(scope.row)"
  70. v-hasPermi="['operation:channels:delete']"
  71. >删除</el-button
  72. >
  73. </template>
  74. </el-table-column>
  75. </el-table>
  76. <!-- 弹窗 -->
  77. <el-dialog
  78. :visible.sync="dialogVisible"
  79. :title="title"
  80. width="1000px"
  81. :before-close="getClose"
  82. >
  83. <el-form
  84. :model="dialogForm"
  85. ref="dialogForm"
  86. :rules="rules"
  87. label-width="auto"
  88. >
  89. <el-form-item label="频道名称:" prop="name" style="width: 300px">
  90. <el-input
  91. v-model="dialogForm.name"
  92. placeholder="请输入规则名称"
  93. :disabled="readOnly"
  94. />
  95. </el-form-item>
  96. <el-form-item label="关联设备:" prop="deviceIds">
  97. <el-select
  98. v-model="dialogForm.deviceIds"
  99. filterable
  100. multiple
  101. placeholder="请选择关联设备"
  102. :disabled="readOnly"
  103. >
  104. <el-option
  105. v-for="item in devOptions"
  106. :key="item.clientTypeId"
  107. :value="item.clientTypeId"
  108. :label="item.name"
  109. />
  110. </el-select>
  111. </el-form-item>
  112. <el-form-item v-if="dialogForm.id" label="个人频道分类:">
  113. <div class="classList" v-if="readOnly">
  114. <el-button
  115. v-for="item in dialogForm.personalChannelList"
  116. :key="item.channelTypeId"
  117. :type="active === item.sort ? 'primary' : ''"
  118. size="small"
  119. @click="getActive(item)"
  120. >
  121. {{ item.channelTypeName }}
  122. </el-button>
  123. </div>
  124. <div class="classList" v-else>
  125. <!-- isFix:0 不可以编辑删除 -->
  126. <el-button
  127. :type="active === item.sort ? 'primary' : ''"
  128. v-for="item in dialogForm.personalChannelList.filter(
  129. (i) => i.isFix === 0
  130. )"
  131. :key="item.channelTypeId"
  132. size="small"
  133. @click="getActive(item)"
  134. >
  135. {{ item.channelTypeName }}
  136. </el-button>
  137. <!-- isFix:1 可以编辑删除 -->
  138. <el-dropdown
  139. v-for="item in dialogForm.personalChannelList.filter(
  140. (i) => i.isFix === 1
  141. )"
  142. :key="item.channelTypeId"
  143. >
  144. <el-button
  145. :type="active === item.sort ? 'primary' : ''"
  146. size="small"
  147. @click="getActive(item)"
  148. >
  149. {{ item.channelTypeName
  150. }}<i class="el-icon-arrow-down" style="margin-left: 10px" />
  151. </el-button>
  152. <el-dropdown-menu slot="dropdown">
  153. <el-dropdown-item>
  154. <div @click="getInputDialog(item)">编辑</div>
  155. </el-dropdown-item>
  156. <el-dropdown-item>
  157. <div @click="getDelete(item)">删除</div>
  158. </el-dropdown-item>
  159. </el-dropdown-menu>
  160. </el-dropdown>
  161. <el-button
  162. v-if="dialogForm.personalChannelList.length < 9"
  163. icon="el-icon-plus"
  164. size="small"
  165. @click="getCreateDialog(0)"
  166. >新增</el-button
  167. >
  168. </div>
  169. </el-form-item>
  170. <el-form-item v-if="dialogForm.id" label="其他频道分类:">
  171. <div class="classList" v-if="readOnly">
  172. <el-button
  173. v-for="item in dialogForm.otherChannelList"
  174. :key="item.channelTypeId"
  175. :type="active === item.sort ? 'primary' : ''"
  176. size="small"
  177. @click="getActive(item)"
  178. >
  179. {{ item.channelTypeName }}
  180. </el-button>
  181. </div>
  182. <div class="classList" v-else>
  183. <el-dropdown
  184. v-for="item in dialogForm.otherChannelList"
  185. :key="item.channelTypeId"
  186. >
  187. <el-button
  188. :type="active === item.sort ? 'primary' : ''"
  189. size="small"
  190. @click="getActive(item)"
  191. >
  192. {{ item.channelTypeName
  193. }}<i class="el-icon-arrow-down" style="margin-left: 10px" />
  194. </el-button>
  195. <el-dropdown-menu slot="dropdown">
  196. <el-dropdown-item>
  197. <div @click="getInputDialog(item)">编辑</div>
  198. </el-dropdown-item>
  199. <el-dropdown-item>
  200. <div @click="getDelete(item)">删除</div>
  201. </el-dropdown-item>
  202. </el-dropdown-menu>
  203. </el-dropdown>
  204. <el-button
  205. icon="el-icon-plus"
  206. size="small"
  207. @click="getCreateDialog(1)"
  208. >新增</el-button
  209. >
  210. </div>
  211. </el-form-item>
  212. </el-form>
  213. <el-table v-show="dialogForm.id" :data="dialogForm.defaultList">
  214. <el-table-column
  215. label="频道号"
  216. align="center"
  217. prop="channelId"
  218. width="75px"
  219. />
  220. <el-table-column
  221. label="频道名称"
  222. align="center"
  223. prop="aliasName"
  224. show-overflow-tooltip
  225. />
  226. <el-table-column label="频道封面" align="center" width="100px">
  227. <template slot-scope="scope">
  228. <el-image :src="scope.row.pic" />
  229. </template>
  230. </el-table-column>
  231. <el-table-column
  232. label="频道简介"
  233. align="center"
  234. prop="description"
  235. show-overflow-tooltip
  236. />
  237. <el-table-column label="操作" align="center">
  238. <template slot-scope="scope">
  239. <el-button type="text" @click="getRouter(scope, true)"
  240. >查看</el-button
  241. >
  242. <el-button
  243. type="text"
  244. @click="getRouter(scope)"
  245. :disabled="readOnly"
  246. >编辑</el-button
  247. >
  248. <el-button
  249. v-if="scope.row.sort > 3"
  250. type="text"
  251. icon="el-icon-caret-top"
  252. @click="getChange(scope.row, scope.row.sort - 1)"
  253. :disabled="readOnly"
  254. />
  255. <el-button
  256. v-if="scope.row.sort > 2 && scope.row.sort < 12"
  257. type="text"
  258. icon="el-icon-caret-bottom"
  259. @click="getChange(scope.row, scope.row.sort + 1)"
  260. :disabled="readOnly"
  261. />
  262. </template>
  263. </el-table-column>
  264. </el-table>
  265. <div v-if="!readOnly" slot="footer">
  266. <el-button @click="getClose">取消</el-button>
  267. <el-button type="primary" @click="getSubmit">确定</el-button>
  268. </div>
  269. </el-dialog>
  270. <el-dialog
  271. :visible.sync="inputVisible"
  272. :title="classTitle"
  273. width="500px"
  274. :before-close="getInputClose"
  275. >
  276. <el-form :model="classForm" ref="classForm" label-width="auto">
  277. <el-form-item
  278. label="分类名称:"
  279. prop="channelTypeName"
  280. :rules="[
  281. { required: true, message: '请输入分类名称', trigger: 'blur' },
  282. { max: 6, message: '不可超过6个字符', trigger: 'blur' },
  283. ]"
  284. >
  285. <el-input
  286. v-model="classForm.channelTypeName"
  287. placeholder="请输入分类名称"
  288. />
  289. </el-form-item>
  290. </el-form>
  291. <div slot="footer">
  292. <el-button @click="getInputClose">取消</el-button>
  293. <el-button type="primary" @click="getInputSubmit">确定</el-button>
  294. </div>
  295. </el-dialog>
  296. </div>
  297. </template>
  298. <script>
  299. import {
  300. change,
  301. channels,
  302. classEdit,
  303. classRemove,
  304. classSubmit,
  305. detail,
  306. dev,
  307. edit,
  308. list,
  309. remove,
  310. submit
  311. } from "@/api/operation/channels";
  312. import { dialogCallBack } from "@/utils/DialogUtil";
  313. export default {
  314. name: "OperationChannels",
  315. data() {
  316. return {
  317. editData: {
  318. currentEditIndex: -1,
  319. currentEditSort: 1,
  320. },
  321. // 遮罩层
  322. loading: false,
  323. // 列表
  324. tableData: [],
  325. // 全部设备列表
  326. allDevOptions: [],
  327. // 剔除已选的设备列表
  328. devOptions: [],
  329. // 弹窗
  330. dialogVisible: false,
  331. // 查看
  332. readOnly: false,
  333. // 弹窗名称
  334. title: "新增",
  335. classTitle: "新增",
  336. // 弹窗表单
  337. dialogForm: {
  338. deviceIds: [],
  339. },
  340. row: {},
  341. // 分类焦点
  342. active: 0,
  343. // 分类弹窗
  344. inputVisible: false,
  345. // 分类表单
  346. classForm: {},
  347. // 分类类型
  348. type: null,
  349. // 校验
  350. rules: {
  351. name: [
  352. {
  353. required: true,
  354. message: "请输入规则名称",
  355. trigger: "blur",
  356. },
  357. ],
  358. deviceIds: [
  359. {
  360. required: true,
  361. message: "请选择关联设备",
  362. trigger: "change",
  363. },
  364. ],
  365. },
  366. };
  367. },
  368. async mounted() {
  369. await this.getDev(1);
  370. this.getList();
  371. },
  372. methods: {
  373. // 设备列表
  374. async getDev(type) {
  375. await dev(type).then((res) => {
  376. if (type === 0) {
  377. this.devOptions = res.data;
  378. } else {
  379. this.allDevOptions = res.data;
  380. }
  381. });
  382. },
  383. // 列表
  384. getList() {
  385. this.loading = true;
  386. list().then((res) => {
  387. if (res.code === 0) {
  388. var data = res.data;
  389. for (var i = 0; i < data.length; i++) {
  390. data[i].indexNum = i + 1;
  391. }
  392. this.tableData = data;
  393. this.loading = false;
  394. }
  395. });
  396. },
  397. // 删除频道规则
  398. getRemove(row) {
  399. var that = this;
  400. dialogCallBack(that, function () {
  401. that.$confirm(`是否删除${row.name}?`, "提示:").then(() => {
  402. remove(row.id).then((res) => {
  403. if (res.code === 0) {
  404. that.$message.success("删除成功!");
  405. that.getList();
  406. }
  407. });
  408. });
  409. });
  410. },
  411. // 点击编辑图标显示输入框
  412. handleEditClick(row, index) {
  413. this.editData.currentEditIndex = index;
  414. this.editData.currentEditSort = row.indexNum;
  415. this.$nextTick(() => {
  416. this.$refs.numberInput.focus();
  417. });
  418. },
  419. onNumberBlurEnter(row, index) {
  420. this.editData.currentEditIndex = -1;
  421. },
  422. // 输入框失去焦点时隐藏
  423. onNumberBlur(row, index) {
  424. var newSort = row.indexNum;
  425. if (newSort === "") {
  426. row.indexNum = this.editData.currentEditSort;
  427. this.$message.warning("序号不能为空");
  428. return;
  429. }
  430. if (newSort <= 0) {
  431. row.indexNum = this.editData.currentEditSort;
  432. this.$message.warning("序号必须大于0");
  433. return;
  434. }
  435. if (newSort === this.editData.currentEditSort) {
  436. this.editData.currentEditIndex = -1;
  437. return;
  438. }
  439. ///删除第index个元素
  440. this.tableData.splice(index, 1);
  441. this.tableData.splice(newSort - 1, 0, row);
  442. for (var i = 0; i < this.tableData.length; i++) {
  443. this.tableData[i].indexNum = i + 1;
  444. }
  445. this.editData.currentEditIndex = -1;
  446. // channeledit(this.tableData).then((res) => {
  447. // console.log("编辑成功:", JSON.stringify(res));
  448. // if (res.code === 0) {
  449. // this.$message.success("编辑成功!");
  450. // this.getList();
  451. // }
  452. // });
  453. // 检查序号是否重复
  454. // const isDuplicate = this.tableData.some(
  455. // (item, i) => i !== index && item.sortIndex === newSort
  456. // );
  457. // if (isDuplicate) {
  458. // this.$message.warning("序号已存在");
  459. // } else {
  460. // // 更新到tableData
  461. // this.$set(this.tableData, index, {
  462. // ...row,
  463. // sortIndex: newSort,
  464. // });
  465. // console.log(
  466. // "序号修改成功:",
  467. // newSort,
  468. // "row.sortIndex",
  469. // row.sortIndex,
  470. // "this.tableData",
  471. // this.tableData[index].sortIndex
  472. // );
  473. // 隐藏编辑框
  474. // this.editData.currentEditIndex = -1;
  475. // }
  476. },
  477. // 弹窗
  478. async getDialog(row, boolean) {
  479. this.dialogVisible = true;
  480. this.readOnly = boolean;
  481. await this.getDev(0);
  482. if (row !== undefined) {
  483. this.row = row;
  484. this.devOptions.unshift.apply(this.devOptions, this.row.deviceList);
  485. this.getDetail();
  486. }
  487. },
  488. //弹窗 详情
  489. getDetail() {
  490. detail(this.row.id).then((res) => {
  491. if (res.code === 0) {
  492. this.dialogForm = res.data;
  493. this.dialogForm.deviceIds = res.data.deviceIds.split(",");
  494. }
  495. });
  496. },
  497. //弹窗 获取焦点
  498. getActive(item) {
  499. this.active = item.sort;
  500. this.getChannels(item.channelTypeId);
  501. },
  502. //弹窗 12频道
  503. getChannels(id) {
  504. channels(id).then((res) => {
  505. if (res.code === 0) {
  506. this.dialogForm.defaultList = res.data;
  507. }
  508. });
  509. },
  510. // 打开分类弹窗
  511. getInputDialog(item) {
  512. this.inputVisible = true;
  513. this.classTitle = "编辑";
  514. this.classForm = JSON.parse(JSON.stringify(item));
  515. },
  516. getCreateDialog(type) {
  517. this.inputVisible = true;
  518. this.classTitle = "新增";
  519. this.type = type;
  520. },
  521. // 关闭分类表单
  522. getInputClose() {
  523. this.inputVisible = false;
  524. this.type = null;
  525. this.classForm = {};
  526. this.$refs.classForm.resetFields();
  527. },
  528. // 提交分类表单
  529. getInputSubmit() {
  530. this.$refs.classForm.validate((valid) => {
  531. if (valid) {
  532. if (this.type === null) {
  533. classEdit(
  534. this.classForm.channelTypeName,
  535. this.classForm.channelTypeId
  536. ).then((res) => {
  537. if (res.code === 0) {
  538. this.getInputClose();
  539. this.$message.success("编辑成功!");
  540. this.getDetail();
  541. }
  542. });
  543. } else {
  544. classSubmit(
  545. this.classForm.channelTypeName,
  546. this.type,
  547. this.dialogForm.id
  548. ).then((res) => {
  549. if (res.code === 0) {
  550. this.getInputClose();
  551. this.$message.success("新增成功!");
  552. this.getDetail();
  553. }
  554. });
  555. }
  556. } else {
  557. return false;
  558. }
  559. });
  560. },
  561. // 提交
  562. getSubmit() {
  563. this.$refs.dialogForm.validate((valid) => {
  564. if (valid) {
  565. this.dialogForm.deviceIds = this.dialogForm.deviceIds.join(",");
  566. if (this.dialogForm.id) {
  567. edit(this.dialogForm).then((res) => {
  568. if (res.code === 0) {
  569. this.$message.success("编辑成功!");
  570. this.getClose();
  571. this.getList();
  572. }
  573. });
  574. } else {
  575. submit(this.dialogForm).then((res) => {
  576. if (res.code === 0) {
  577. this.$message.success("提交成功!");
  578. this.getClose();
  579. this.getList();
  580. }
  581. });
  582. }
  583. } else {
  584. return false;
  585. }
  586. });
  587. },
  588. // 取消
  589. getClose() {
  590. this.dialogVisible = false;
  591. this.dialogForm = {};
  592. this.$refs.dialogForm.resetFields();
  593. },
  594. // 删除
  595. getDelete(item) {
  596. var that = this;
  597. dialogCallBack(that, function () {
  598. that
  599. .$confirm(`是否删除${item.channelTypeName}?`, "提示:")
  600. .then(() => {
  601. classRemove(item.channelTypeId).then((res) => {
  602. if (res.code === 0) {
  603. that.$message.success("删除成功!");
  604. that.getDetail();
  605. }
  606. });
  607. })
  608. .catch(() => {});
  609. });
  610. },
  611. // 12频道详情
  612. getRouter(e, boolean) {
  613. this.$router.push({
  614. path: `/operation/channels/detail`,
  615. query: {
  616. channelId: e.row.id,
  617. audioType: e.row.channelType,
  618. index: e.$index,
  619. boolean: boolean,
  620. },
  621. });
  622. },
  623. // 排序
  624. getChange(row, sort) {
  625. change({
  626. id: row.id,
  627. sort: sort,
  628. }).then((res) => {
  629. if (res.code === 0) {
  630. this.$message.success("修改成功!");
  631. this.getChannels(row.templateCategoryId);
  632. }
  633. });
  634. },
  635. },
  636. };
  637. </script>
  638. <style lang="scss" scoped>
  639. .classList {
  640. ::v-deep .el-button {
  641. margin: 0 10px 10px 0;
  642. }
  643. }
  644. </style>