announcement.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. <template>
  2. <div class="hc-system-announcement-box">
  3. <div class="card-body">
  4. <div class="card-main">
  5. <div class="header">
  6. <div class="title">
  7. <div style="width: 140px">
  8. <el-select v-model="searchForm.msgType" class="block" clearable filterable placeholder="请选择公告类型" size="small">
  9. <el-option label="更新公告" value="1"></el-option>
  10. <el-option label="普通公告" value="2"></el-option>
  11. </el-select>
  12. </div>
  13. <div style="width: 100px; margin-left: 12px; margin-right: 12px;">
  14. <el-select v-model="searchForm.pushStatus" class="block" clearable filterable placeholder="发布状态" size="small">
  15. <el-option label="待发布" value="1"></el-option>
  16. <el-option label="已发布" value="2"></el-option>
  17. <el-option label="已取消" value="3"></el-option>
  18. </el-select>
  19. </div>
  20. <el-button size="small" type="primary" @click="searchClick">搜索</el-button>
  21. </div>
  22. <div class="extra">
  23. <el-badge :value="releasedNum" style="margin-right: 18px;">
  24. <el-button size="small" @click="releasedShow">待发布</el-button>
  25. </el-badge>
  26. <el-button size="small" type="primary" @click="generalShow">发布普通公告</el-button>
  27. <el-button size="small" type="warning" @click="systemUpdateShow">发布系统公告</el-button>
  28. <el-button size="small" type="danger" @click="handleDelete">批量删除公告</el-button>
  29. </div>
  30. </div>
  31. <div class="content" v-loading="isLoading">
  32. <el-table ref="tableRef" :data="tableData" border style="width: 100%;" height="100%" @selection-change="tableSelection">
  33. <el-table-column type="selection" width="50" align="center" fixed="left"></el-table-column>
  34. <el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
  35. <el-table-column prop="msgType" label="公告类型" width="140">
  36. <template slot-scope="{row}">
  37. <span v-if="row.msgType===1">更新公告</span>
  38. <span v-if="row.msgType===2">普通公告</span>
  39. </template>
  40. </el-table-column>
  41. <el-table-column prop="pushSystem" label="推送系统" min-width="120"></el-table-column>
  42. <el-table-column prop="msgContent" label="公告内容" min-width="240"></el-table-column>
  43. <el-table-column prop="pushRemark" label="发布备注" width="300"></el-table-column>
  44. <el-table-column prop="pushDateTime" label="发布时间" width="180"></el-table-column>
  45. <el-table-column prop="pushDateTime" label="时间配置" width="340">
  46. <template slot-scope="{row}">
  47. <template v-if="row.msgType===1">
  48. <span>剩余</span>
  49. <el-tag type="danger" effect="dark" size="mini">{{row.msgWarnTime}}分钟</el-tag>
  50. <span>进行提醒,</span>
  51. <el-tag type="danger" effect="dark" size="mini">{{row.msgCountDownTime}}分钟</el-tag>
  52. <span>开始进入倒计时</span>
  53. </template>
  54. <template v-else>
  55. <span>-</span>
  56. </template>
  57. </template>
  58. </el-table-column>
  59. <el-table-column prop="creatUserName" label="创建人" width="100"></el-table-column>
  60. <el-table-column prop="cancelDateTime" label="取消时间" width="180"></el-table-column>
  61. <el-table-column prop="pushStatus" label="发布状态" width="80" align="center">
  62. <template slot-scope="{row}">
  63. <el-tag type="danger" effect="dark" size="mini" v-if="row.pushStatus===3">已取消</el-tag>
  64. <el-tag type="success" effect="dark" size="mini" v-if="row.pushStatus===2">已发布</el-tag>
  65. <el-tag type="info" effect="dark" size="mini" v-if="row.pushStatus===1">待发布</el-tag>
  66. </template>
  67. </el-table-column>
  68. <el-table-column prop="action" label="操作" width="180" align="center" fixed="right">
  69. <template slot-scope="{row}">
  70. <el-button size="mini" @click="handleEdit(row)" :disabled="row.pushStatus!==3">编辑</el-button>
  71. <el-button size="mini" type="danger" @click="handleCancel(row)" :disabled="row.pushStatus!==1">取消发布</el-button>
  72. </template>
  73. </el-table-column>
  74. </el-table>
  75. </div>
  76. <div class="action">
  77. <el-pagination
  78. @size-change="handleSizeChange"
  79. @current-change="handleCurrentChange"
  80. :current-page="searchForm.current"
  81. :page-sizes="[20, 30, 40, 50]"
  82. :page-size="searchForm.size"
  83. layout="total, prev, pager, next, sizes, jumper"
  84. :total="searchForm.total"
  85. >
  86. </el-pagination>
  87. </div>
  88. </div>
  89. </div>
  90. <!--待发布-->
  91. <el-dialog
  92. class="hc-system-announcement-dialog black-card" title="待发布的公告" :visible.sync="isReleasedShow"
  93. append-to-body center destroy-on-close width="660px" @closed="releasedCancel"
  94. >
  95. <el-divider content-position="left" class="hc-system-announcement-black-divider top" v-if="releasedData.updateMsg.length > 0">更新公告</el-divider>
  96. <div class="hc-system-announcement-black-card" v-for="(item, index) in releasedData.updateMsg" :key="index">
  97. <div class="icon-box">
  98. <div class="name">{{index === 0?'前 端':'后 端'}}</div>
  99. <div class="icon">
  100. <i class="iconfont iconicon_notice"></i>
  101. </div>
  102. </div>
  103. <div class="content">
  104. <div class="top-box">
  105. <div class="left">
  106. <span class="name">待发布:</span>
  107. <span class="num">{{item.awaitMsgTotal}}</span>
  108. </div>
  109. <div class="right">
  110. <span class="name">创建人:</span>
  111. <span class="user">{{item.creatUserName}}</span>
  112. </div>
  113. </div>
  114. <div class="time-box">
  115. <span class="name">发布时间:</span>
  116. <span class="time">{{item.pushDateTime}}</span>
  117. </div>
  118. </div>
  119. </div>
  120. <el-divider content-position="left" class="hc-system-announcement-black-divider" v-if="releasedData.systemMsg.length > 0">普通公告</el-divider>
  121. <div class="hc-system-announcement-black-card" v-for="(item, index) in releasedData.systemMsg" :key="index">
  122. <div class="icon-box">
  123. <div class="name">公 告</div>
  124. <div class="icon">
  125. <i class="iconfont iconicon_notice"></i>
  126. </div>
  127. </div>
  128. <div class="content">
  129. <div class="top-box">
  130. <div class="left">
  131. <span class="name">待发布:</span>
  132. <span class="num">{{item.awaitMsgTotal}}</span>
  133. </div>
  134. <div class="right">
  135. <span class="name">创建人:</span>
  136. <span class="user">{{item.creatUserName}}</span>
  137. </div>
  138. </div>
  139. <div class="time-box">
  140. <span class="name">发布时间:</span>
  141. <span class="time">{{item.pushDateTime}}</span>
  142. </div>
  143. </div>
  144. </div>
  145. </el-dialog>
  146. <!--发布普通公告-->
  147. <el-dialog
  148. class="hc-system-announcement-dialog w-700px" title="发布普通公告" :visible.sync="isGeneralShow"
  149. width="700px" append-to-body center destroy-on-close @closed="generalCancel"
  150. >
  151. <el-form :model="generalFormModel" :rules="generalFormRules" ref="generalFormRef" class="hc-system-announcement-form" label-width="auto">
  152. <el-form-item label="公告内容:" prop="msgContent">
  153. <el-input type="textarea" v-model="generalFormModel.msgContent" rows="3"></el-input>
  154. </el-form-item>
  155. <el-form-item label="发布备注:" prop="pushRemark">
  156. <el-input type="textarea" v-model="generalFormModel.pushRemark"></el-input>
  157. </el-form-item>
  158. <el-form-item label="发布配置:" prop="pushDateTime">
  159. <el-date-picker v-model="generalFormModel.pushDateTime" type="datetime" placeholder="选择日期时间" :picker-options="pickerOptions" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"></el-date-picker>
  160. </el-form-item>
  161. <el-form-item label="停留时间:" prop="msgShowTime">
  162. <el-select v-model="generalFormModel.msgShowTime" clearable filterable style="width: 190px;">
  163. <el-option v-for="i in 60" :label="`${i}分钟`" :value="i"></el-option>
  164. </el-select>
  165. </el-form-item>
  166. <el-form-item label="涉及系统:" prop="pushSystem">
  167. <el-checkbox-group v-model="generalFormModel.pushSystem">
  168. <el-checkbox v-for="item in systemClinet" :label="item.clientId">{{item.name || item.clientId}}</el-checkbox>
  169. </el-checkbox-group>
  170. </el-form-item>
  171. </el-form>
  172. <div slot="footer">
  173. <el-button @click="generalCancel">取消</el-button>
  174. <el-button type="primary" @click="generalFormSubmit">发布</el-button>
  175. </div>
  176. </el-dialog>
  177. <!--发布系统公告-->
  178. <el-dialog
  179. class="hc-system-announcement-dialog h-full w-700px" title="发布系统公告" :visible.sync="isSystemUpdateShow"
  180. width="700px" append-to-body center destroy-on-close @closed="systemUpdateCancel"
  181. >
  182. <el-form :model="updateFormModel" :rules="updateFormRules" ref="updateFormRef" class="hc-system-announcement-form" label-width="auto">
  183. <el-form-item label="公告内容:" prop="msgContent">
  184. <el-input type="textarea" v-model="updateFormModel.msgContent" rows="3"></el-input>
  185. </el-form-item>
  186. <el-form-item label="发布备注:" prop="pushRemark">
  187. <el-input type="textarea" v-model="updateFormModel.pushRemark"></el-input>
  188. </el-form-item>
  189. <el-form-item label="更新类型:" prop="updateServerType">
  190. <el-checkbox-group v-model="updateFormModel.updateServerType">
  191. <el-checkbox label="1">前端页面</el-checkbox>
  192. <el-checkbox label="2">后端接口</el-checkbox>
  193. </el-checkbox-group>
  194. </el-form-item>
  195. <el-form-item label="更新原因:" prop="updateCodeType">
  196. <el-radio-group v-model="updateFormModel.updateCodeType">
  197. <el-radio label="1">新功能需求</el-radio>
  198. <el-radio label="2">bug修复</el-radio>
  199. </el-radio-group>
  200. </el-form-item>
  201. <el-form-item label="发布配置:" prop="pushDateTime">
  202. <el-date-picker v-model="updateFormModel.pushDateTime" type="datetime" placeholder="选择日期时间" :picker-options="pickerOptions" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"></el-date-picker>
  203. </el-form-item>
  204. <el-form-item label="时间配置:" prop="msgWarnTime">
  205. <span>剩余</span>
  206. <span style="margin-left: 5px">
  207. <el-select v-model="updateFormModel.msgWarnTime" clearable filterable size="small" style="width: 90px;" placeholder="分钟">
  208. <el-option v-for="i in 60" :label="`${i}分钟`" :value="i"></el-option>
  209. </el-select>
  210. </span>
  211. <span style="margin-left: 5px">进行提醒,</span>
  212. <span style="margin-left: 5px">
  213. <el-select v-model="updateFormModel.msgCountDownTime" clearable filterable size="small" style="width: 90px;" placeholder="时间">
  214. <el-option v-for="i in 60" :label="`${i}分钟`" :value="i"></el-option>
  215. </el-select>
  216. </span>
  217. <span style="margin-left: 5px">开始进入倒计时</span>
  218. </el-form-item>
  219. <el-form-item label="涉及系统:" prop="pushSystem">
  220. <el-checkbox-group v-model="updateFormModel.pushSystem">
  221. <el-checkbox v-for="item in systemClinet" :label="item.clientId">{{item.name || item.clientId}}</el-checkbox>
  222. </el-checkbox-group>
  223. </el-form-item>
  224. </el-form>
  225. <div slot="footer">
  226. <el-button @click="systemUpdateCancel">取消</el-button>
  227. <el-button type="primary" @click="updateFormSubmit">发布</el-button>
  228. </div>
  229. </el-dialog>
  230. </div>
  231. </template>
  232. <script>
  233. import '@/styles/announcement.scss'
  234. import {getList, getAwaitMsg, getClinetAll, add, update, cancelPush, remove} from "@/api/system/announcement";
  235. export default {
  236. data() {
  237. return {
  238. //搜索
  239. searchForm: {current: 1, size: 20, total: 0},
  240. //公告列表
  241. isLoading: false,
  242. tableData: [],
  243. tableMultiple: [],
  244. //待发布
  245. isReleasedShow: false,
  246. releasedNum: 0,
  247. releasedData: {
  248. systemMsg: [],
  249. updateMsg: []
  250. },
  251. //普通公告
  252. isGeneralShow: false,
  253. generalFormModel: {
  254. pushSystem: [],
  255. },
  256. generalFormRules: {
  257. msgContent: [
  258. { required: true, message: '请填写公告内容', trigger: 'blur' }
  259. ],
  260. pushDateTime: [
  261. { required: true, message: '请选择发布配置', trigger: 'blur' }
  262. ],
  263. msgShowTime: [
  264. { required: true, message: '请选择停留时间', trigger: 'blur' }
  265. ],
  266. pushSystem: [
  267. { required: true, message: '请选择涉及系统', trigger: 'blur' }
  268. ]
  269. },
  270. //系统更新
  271. isSystemUpdateShow: false,
  272. updateFormModel: {
  273. updateServerType: [],
  274. pushSystem: []
  275. },
  276. updateFormRules: {
  277. msgContent: [
  278. { required: true, message: '请填写公告内容', trigger: 'blur' }
  279. ],
  280. updateServerType: [
  281. { required: true, message: '请选择更新类型', trigger: 'blur' }
  282. ],
  283. updateCodeType: [
  284. { required: true, message: '请选择更新原因', trigger: 'blur' }
  285. ],
  286. pushDateTime: [{
  287. required: true, trigger: 'blur',
  288. validator: (rule, value, callback) => {
  289. const {msgCountDownTime} = this.updateFormModel
  290. if (!value) {
  291. callback(new Error('请选择剩余进行提醒时间'));
  292. } else if (!msgCountDownTime) {
  293. callback(new Error('请选择进入倒计时时间'));
  294. } else {
  295. callback();
  296. }
  297. }
  298. }],
  299. msgWarnTime: [
  300. { required: true, message: '请选择时间配置', trigger: 'blur' }
  301. ],
  302. pushSystem: [
  303. { required: true, message: '请选择涉及系统', trigger: 'blur' }
  304. ]
  305. },
  306. systemClinet: [],
  307. //日期时间
  308. pickerOptions: {
  309. shortcuts: [{
  310. text: '三分钟',
  311. onClick(picker) {
  312. const date = new Date();
  313. date.setTime(date.getTime() + 3 * 60 * 1000);
  314. picker.$emit('pick', date);
  315. }
  316. }, {
  317. text: '五分钟',
  318. onClick(picker) {
  319. const date = new Date();
  320. date.setTime(date.getTime() + 5 * 60 * 1000);
  321. picker.$emit('pick', date);
  322. }
  323. }, {
  324. text: '十分钟',
  325. onClick(picker) {
  326. const date = new Date();
  327. date.setTime(date.getTime() + 10 * 60 * 1000);
  328. picker.$emit('pick', date);
  329. }
  330. }, {
  331. text: '三十分钟',
  332. onClick(picker) {
  333. const date = new Date();
  334. date.setTime(date.getTime() + 30 * 60 * 1000);
  335. picker.$emit('pick', date);
  336. }
  337. }]
  338. },
  339. }
  340. },
  341. created() {
  342. this.searchClick()
  343. this.getAwaitMsgApi()
  344. },
  345. methods: {
  346. //获取待发布公告
  347. async getAwaitMsgApi() {
  348. let _this = this
  349. getAwaitMsg().then(({data}) => {
  350. const {msgTotal, systemMsg, updateMsg} = data.data || {}
  351. _this.releasedData = {
  352. systemMsg: systemMsg,
  353. updateMsg: updateMsg
  354. }
  355. _this.releasedNum = msgTotal
  356. })
  357. },
  358. handleSizeChange(val) {
  359. this.searchForm.size = val
  360. },
  361. handleCurrentChange(val) {
  362. this.searchForm.current = val
  363. },
  364. //搜索
  365. searchClick() {
  366. this.searchForm.current = 1
  367. this.getTableData()
  368. },
  369. //获取表格数据
  370. async getTableData() {
  371. this.isLoading = true
  372. const res = await getList(this.searchForm)
  373. const {code, data, msg} = res.data || {}
  374. const {records, total} = data || {}
  375. this.tableData = records
  376. this.searchForm.total = total
  377. if (code!==200) {
  378. this.$message.error(msg);
  379. }
  380. this.isLoading = false
  381. },
  382. //表格多选
  383. tableSelection(val) {
  384. this.tableMultiple = val
  385. },
  386. //表格编辑
  387. handleEdit(row) {
  388. const form = JSON.parse(JSON.stringify(row));
  389. if (form.msgType === 1) {
  390. form.updateServerType = form.updateServerType.split(',')
  391. form.pushSystem = form.pushSystem.split(',')
  392. this.updateFormModel = form
  393. this.systemUpdateShow()
  394. } else {
  395. form.pushSystem = form.pushSystem.split(',')
  396. this.generalFormModel = form
  397. this.generalShow()
  398. }
  399. },
  400. //表格删除
  401. async handleDelete() {
  402. const arr = this.tableMultiple
  403. if (arr.length<=0) {
  404. this.$message.warning('请先勾选数据');
  405. return
  406. }
  407. //判断是否满足条件
  408. const result = arr.every(({ pushStatus }) => {
  409. return pushStatus === 3
  410. })
  411. if (!result) {
  412. this.$message.error('请选择已取消的数据');
  413. return
  414. }
  415. const ids = arr.flat().map(item => item.id).join(',');
  416. remove(ids).then(({data}) => {
  417. this.$message.success(data.msg || '操作成功');
  418. this.tableMultiple = []
  419. this.searchClick()
  420. this.getAwaitMsgApi()
  421. })
  422. },
  423. //取消发布
  424. handleCancel(row) {
  425. cancelPush(row.id).then(({data}) => {
  426. this.$message.success(data.msg || '操作成功');
  427. this.searchClick()
  428. this.getAwaitMsgApi()
  429. })
  430. },
  431. //待发布打开
  432. releasedShow() {
  433. this.isReleasedShow = true
  434. },
  435. //待发布关闭
  436. releasedCancel() {
  437. this.isReleasedShow = false
  438. },
  439. //打开普通公告
  440. generalShow() {
  441. this.isGeneralShow = true
  442. this.getClinetAllApi()
  443. },
  444. //获取应用列表
  445. async getClinetAllApi() {
  446. const res = await getClinetAll()
  447. const {data} = res.data || []
  448. this.systemClinet = data
  449. },
  450. async generalFormSubmit() {
  451. const isForm = await this.getFormValidate('generalFormRef')
  452. if (!isForm) return
  453. let form = JSON.parse(JSON.stringify(this.generalFormModel))
  454. form.pushSystem = form.pushSystem.join(',')
  455. form.msgType = 2
  456. if (form.id) {
  457. update(form).then(({data}) => {
  458. this.$message.success(data.msg || '操作成功');
  459. this.generalCancel()
  460. this.searchClick()
  461. this.getAwaitMsgApi()
  462. })
  463. } else {
  464. add(form).then(({data}) => {
  465. this.$message.success(data.msg || '操作成功');
  466. this.generalCancel()
  467. this.searchClick()
  468. this.getAwaitMsgApi()
  469. })
  470. }
  471. },
  472. //普通公告关闭
  473. generalCancel() {
  474. this.isGeneralShow = false
  475. this.generalFormModel = {
  476. pushSystem: []
  477. }
  478. },
  479. //系统更新公告
  480. systemUpdateShow() {
  481. this.isSystemUpdateShow = true
  482. this.getClinetAllApi()
  483. },
  484. //系统更新公告提交
  485. async updateFormSubmit() {
  486. const isForm = await this.getFormValidate('updateFormRef')
  487. if (!isForm) return
  488. let form = JSON.parse(JSON.stringify(this.updateFormModel))
  489. form.pushSystem = form.pushSystem.join(',')
  490. form.updateServerType = form.updateServerType.join(',')
  491. form.msgType = 1
  492. if (form.id) {
  493. update(form).then(({data}) => {
  494. this.$message.success(data.msg || '操作成功');
  495. this.systemUpdateCancel()
  496. this.searchClick()
  497. this.getAwaitMsgApi()
  498. })
  499. } else {
  500. add(form).then(({data}) => {
  501. this.$message.success(data.msg || '操作成功');
  502. this.systemUpdateCancel()
  503. this.searchClick()
  504. this.getAwaitMsgApi()
  505. })
  506. }
  507. },
  508. //系统更新公告关闭
  509. systemUpdateCancel() {
  510. this.isSystemUpdateShow = false
  511. this.updateFormModel = {
  512. updateServerType: [],
  513. pushSystem: []
  514. }
  515. },
  516. //验证表单
  517. async getFormValidate(ref) {
  518. return new Promise(resolve => {
  519. if (!ref) {
  520. resolve(false)
  521. return
  522. }
  523. this.$refs[ref].validate((valid) => {
  524. resolve(!!valid)
  525. });
  526. })
  527. }
  528. },
  529. }
  530. </script>