Prechádzať zdrojové kódy

公示公告台账、置顶公告首页滚动

Wang Zi Wen 2 rokov pred
rodič
commit
db8b9b34d3

+ 24 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java

@@ -2,6 +2,8 @@ package com.ruoyi.system.domain;
 
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.Size;
+
+import com.ruoyi.common.annotation.Excel;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 import com.ruoyi.common.core.domain.BaseEntity;
@@ -31,6 +33,28 @@ public class SysNotice extends BaseEntity
     /** 公告状态(0正常 1关闭) */
     private String status;
 
+    /** 是否置顶(1是 0否) */
+    private String isPinned;
+
+    /** 部门id */
+    private Long deptId;
+
+    public Long getDeptId() {
+        return deptId;
+    }
+
+    public void setDeptId(Long deptId) {
+        this.deptId = deptId;
+    }
+
+    public String getIsPinned() {
+        return isPinned;
+    }
+
+    public void setIsPinned(String isPinned) {
+        this.isPinned = isPinned;
+    }
+
     public Long getNoticeId()
     {
         return noticeId;

+ 3 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java

@@ -1,6 +1,8 @@
 package com.ruoyi.system.service.impl;
 
 import java.util.List;
+
+import com.ruoyi.common.annotation.DataScope;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.system.domain.SysNotice;
@@ -37,6 +39,7 @@ public class SysNoticeServiceImpl implements ISysNoticeService
      * @return 公告集合
      */
     @Override
+    @DataScope(deptAlias = "d", userAlias = "u")
     public List<SysNotice> selectNoticeList(SysNotice notice)
     {
         return noticeMapper.selectNoticeList(notice);

+ 59 - 39
ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml

@@ -3,7 +3,7 @@
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.ruoyi.system.mapper.SysNoticeMapper">
-    
+
     <resultMap type="SysNotice" id="SysNoticeResult">
         <result property="noticeId"       column="notice_id"       />
         <result property="noticeTitle"    column="notice_title"    />
@@ -15,75 +15,95 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="updateBy"       column="update_by"       />
         <result property="updateTime"     column="update_time"     />
         <result property="remark"         column="remark"          />
+        <result property="isPinned"         column="is_pinned"          />
+        <result property="deptId"         column="dept_id"          />
     </resultMap>
-    
+
     <sql id="selectNoticeVo">
-        select notice_id, notice_title, notice_type, notice_content, status, create_by, create_time, update_by, update_time, remark
-		from sys_notice
+        select d.notice_id, d.notice_title, d.notice_type, d.notice_content, d.status, d.create_by, d.create_time, d.update_by, d.update_time, d.remark, d.is_pinned, d.dept_id
+		from sys_notice d
     </sql>
-    
+
     <select id="selectNoticeById" parameterType="Long" resultMap="SysNoticeResult">
         <include refid="selectNoticeVo"/>
         where notice_id = #{noticeId}
     </select>
-    
+
     <select id="selectNoticeList" parameterType="SysNotice" resultMap="SysNoticeResult">
         <include refid="selectNoticeVo"/>
         <where>
-			<if test="noticeTitle != null and noticeTitle != ''">
-				AND notice_title like concat('%', #{noticeTitle}, '%')
-			</if>
-			<if test="noticeType != null and noticeType != ''">
-				AND notice_type = #{noticeType}
-			</if>
-			<if test="createBy != null and createBy != ''">
-				AND create_by like concat('%', #{createBy}, '%')
-			</if>
-		</where>
+            <if test="noticeTitle != null and noticeTitle != ''">
+                AND notice_title like concat(concat('%',#{noticeTitle}),'%')
+            </if>
+            <if test="noticeType != null and noticeType != ''">
+                AND notice_type = #{noticeType}
+            </if>
+            <if test="createBy != null and createBy != ''">
+                AND create_by like concat(concat('%',#{createBy}),'%')
+            </if>
+            <if test="isPinned != null and isPinned != ''">
+                AND is_pinned = #{isPinned}
+            </if>
+            <if test="deptId != null and deptId != ''">
+                AND dept_id = #{deptId}
+            </if>
+        </where>
+        <!-- 数据范围过滤 -->
+        ${params.dataScope}
+        order by IS_PINNED desc
     </select>
-    
+
     <insert id="insertNotice" parameterType="SysNotice">
+        <selectKey keyProperty="noticeId" order="BEFORE" resultType="long">
+            select seq_sys_notice.nextval as noticeId from DUAL
+        </selectKey>
         insert into sys_notice (
-			<if test="noticeTitle != null and noticeTitle != '' ">notice_title, </if>
-			<if test="noticeType != null and noticeType != '' ">notice_type, </if>
-			<if test="noticeContent != null and noticeContent != '' ">notice_content, </if>
-			<if test="status != null and status != '' ">status, </if>
-			<if test="remark != null and remark != ''">remark,</if>
- 			<if test="createBy != null and createBy != ''">create_by,</if>
- 			create_time
- 		)values(
-			<if test="noticeTitle != null and noticeTitle != ''">#{noticeTitle}, </if>
-			<if test="noticeType != null and noticeType != ''">#{noticeType}, </if>
-			<if test="noticeContent != null and noticeContent != ''">#{noticeContent}, </if>
-			<if test="status != null and status != ''">#{status}, </if>
-			<if test="remark != null and remark != ''">#{remark},</if>
- 			<if test="createBy != null and createBy != ''">#{createBy},</if>
- 			sysdate
-		)
+        <if test="noticeId != null and noticeId != '' ">notice_id, </if>
+        <if test="noticeTitle != null and noticeTitle != '' ">notice_title, </if>
+        <if test="noticeType != null and noticeType != '' ">notice_type, </if>
+        <if test="noticeContent != null and noticeContent != '' ">notice_content, </if>
+        <if test="status != null and status != '' ">status, </if>
+        <if test="remark != null and remark != ''">remark,</if>
+        <if test="createBy != null and createBy != ''">create_by,</if>
+        <if test="deptId != null">dept_id,</if>
+        create_time,is_pinned
+        )values(
+        <if test="noticeId != null and noticeId != '' ">#{noticeId}, </if>
+        <if test="noticeTitle != null and noticeTitle != ''">#{noticeTitle}, </if>
+        <if test="noticeType != null and noticeType != ''">#{noticeType}, </if>
+        <if test="noticeContent != null and noticeContent != ''">#{noticeContent}, </if>
+        <if test="status != null and status != ''">#{status}, </if>
+        <if test="remark != null and remark != ''">#{remark},</if>
+        <if test="createBy != null and createBy != ''">#{createBy},</if>
+        <if test="deptId != null">#{deptId},</if>
+        sysdate,0
+        )
     </insert>
-	 
+
     <update id="updateNotice" parameterType="SysNotice">
-        update sys_notice 
+        update sys_notice
         <set>
             <if test="noticeTitle != null and noticeTitle != ''">notice_title = #{noticeTitle}, </if>
             <if test="noticeType != null and noticeType != ''">notice_type = #{noticeType}, </if>
             <if test="noticeContent != null">notice_content = #{noticeContent}, </if>
             <if test="status != null and status != ''">status = #{status}, </if>
             <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
+            <if test="isPinned != null and isPinned != ''">is_pinned = #{isPinned},</if>
+            <if test="deptId != null">dept_id = #{deptId},</if>
  			update_time = sysdate
         </set>
         where notice_id = #{noticeId}
     </update>
-	
+
     <delete id="deleteNoticeById" parameterType="Long">
         delete from sys_notice where notice_id = #{noticeId}
     </delete>
-    
+
     <delete id="deleteNoticeByIds" parameterType="Long">
-        delete from sys_notice where notice_id in 
+        delete from sys_notice where notice_id in
         <foreach item="noticeId" collection="array" open="(" separator="," close=")">
             #{noticeId}
         </foreach>
     </delete>
-    
+
 </mapper>

+ 1 - 1
ruoyi-ui/src/views/dashboard/BrithChart.vue

@@ -4,8 +4,8 @@
       <ul class="allBirth">
         <li v-for="(item,index) in politicalBirthdayList" class="info">
           <svg-icon icon-class="dangao" class="dangao"></svg-icon>
-          <span style="padding-left: 20px">{{item.nickName}}</span>
           <span style="padding-left: 20px">{{item.partyEntryTime}}</span>
+          <span style="padding-left: 20px">{{item.nickName}}</span>
         </li>
       </ul>
     </div>

+ 151 - 0
ruoyi-ui/src/views/dashboard/NoticeChart.vue

@@ -0,0 +1,151 @@
+<template>
+  <div>
+    <div class="text-container" :style="{height:height,width:width}">
+      <ul class="allBirth">
+        <li v-for="(item,index) in noticeList" class="info">
+          <span style="padding-left: 20px">{{parseTime(item.createTime, '{yyyy}-{mm}-{dd}')}}</span>
+          <span style="padding-left: 20px">{{item.noticeTitle}}</span>
+        </li>
+      </ul>
+    </div>
+  </div>
+</template>
+
+<script>
+  import { listNotice } from "@/api/system/notice";
+
+  const totalDuration = 2000;
+
+  export default {
+    name: "BrithChart",
+    props: {
+      width: {
+        type: String,
+        default: '100%'
+      },
+      height: {
+        type: String,
+        default: '210px'
+      }
+    },
+    data() {
+      return {
+        // 查询参数
+        queryParams: {},
+        // 公示公告列表
+        noticeList: null,
+      }
+    },
+    created() {
+      this.listNotice();
+    },
+    methods: {
+      /** 查询公示公告列表 */
+      listNotice() {
+        this.queryParams.isPinned = 1;
+        listNotice(this.queryParams).then(response => {
+          this.noticeList = response.rows;
+          //判断是否需要滚动
+          if (this.noticeList.length > 4) {
+            //设置文字滚动一轮时间
+            let elem = document.querySelector('.allBirth');
+            let state = elem.style['animation'];
+            let time = this.noticeList.length * 2
+            elem.style['animation'] = 'myMove ' + time + 's linear infinite';
+            let state1 = elem.style['animation-fill-mode'];
+            elem.style['animation-fill-mode'] = 'forwards';
+            //设置文字无缝滚动高度
+            let param = this.noticeList.length * 50
+            let myFirstkeyframes = "@keyframes myMove{0% {transform: translateY(200px);}100% {transform: translateY(-" + param +"px);}}";
+            let style = document.createElement("style");
+            style.setAttribute("type", "text/css");
+            document.head.appendChild(style);
+            const sheet = style.sheet;
+            sheet.insertRule(myFirstkeyframes, 0);
+          }
+        });
+      },
+    }
+  }
+</script>
+
+<style>
+  .text-container {
+    line-height: 30px;
+    overflow: hidden;
+  }
+
+  .dangao {
+    width: 40px !important;
+    height: 40px !important;
+  }
+
+  .info {
+    font-weight:bold;
+    list-style: none;
+    display: flex;
+    margin: 10px 0 0 0;
+    align-items: center;     /* 垂直居中 */
+    border-radius:5px 5px 5px 5px ;
+    /*border: 2px solid rgba(41, 107, 155, 0.71);*/
+    background-color: transparent;
+  }
+
+  .allBirth {
+    margin: -10px 0 0 0;
+    padding: 0 20px 0 20px;
+    /*animation: myMove 10s linear infinite;
+    animation-fill-mode: forwards;*/
+  }
+
+  /*文字无缝滚动*/
+  /*@keyframes myMove {
+    0% {
+      transform: translateY(200px);
+    }
+    100% {
+      transform: translateY(-300px);
+    }
+  }*/
+
+  /*文字停顿滚动*/
+  @keyframes myMove2 {
+    0% {
+      transform: translateY(0);
+    }
+    10% {
+      transform: translateY(-30px);
+    }
+    20% {
+      transform: translateY(-30px);
+    }
+    30% {
+      transform: translateY(-60px);
+    }
+    40% {
+      transform: translateY(-60px);
+    }
+    50% {
+      transform: translateY(-90px);
+    }
+    60% {
+      transform: translateY(-90px);
+    }
+    70% {
+      transform: translateY(-120px);
+    }
+    80% {
+      transform: translateY(-120px);
+    }
+    90% {
+      transform: translateY(-150px);
+    }
+    100% {
+      transform: translateY(-150px);
+    }
+  }
+
+  .info span {
+    padding-top: 5px;
+  }
+</style>

+ 14 - 39
ruoyi-ui/src/views/index.vue

@@ -22,54 +22,28 @@
       <el-col :xs="24" :sm="24" :md="12" :lg="8">
         <el-card class="update-log">
           <div slot="header" class="clearfix">
-        <span class="title">
-          通知公告
-        </span>
+            <span class="title">
+              公示公告
+            </span>
           </div>
           <div class="body">
-            <p>
-              <a class="link">让党旗在疫情防控一线高高飘扬...</a>
-              <span class="date">2022-05-10</span>
-            </p>
-            <p>
-              <a class="link">我校王昕、李新宁作为“四进”攻坚工作组...</a>
-              <span class="date">2022-04-04</span>
-            </p>
-            <p>
-              <a class="link">“第一书记”帮包村客人来我校赠送锦旗</a>
-              <span class="date">2021-05-31</span>
-            </p>
-            <p>
-              <a class="link">我校第三轮“第一书记”载誉归来</a>
-              <span class="date">2019-04-25</span>
-            </p>
+            <div class="chart-wrapper">
+              <notice-chart />
+            </div>
           </div>
         </el-card>
       </el-col>
       <el-col :xs="24" :sm="24" :md="12" :lg="8">
         <el-card class="update-log">
           <div slot="header" class="clearfix">
-        <span class="title">
-          先进风采
-        </span>
+            <span class="title">
+              先进风采
+            </span>
           </div>
           <div class="body">
-            <p>
-              <a class="link">让党旗在疫情防控一线高高飘扬...</a>
-              <span class="date">2022-05-10</span>
-            </p>
-            <p>
-              <a class="link">我校王昕、李新宁作为“四进”攻坚工作组...</a>
-              <span class="date">2022-04-04</span>
-            </p>
-            <p>
-              <a class="link">“第一书记”帮包村客人来我校赠送锦旗</a>
-              <span class="date">2021-05-31</span>
-            </p>
-            <p>
-              <a class="link">我校第三轮“第一书记”载誉归来</a>
-              <span class="date">2019-04-25</span>
-            </p>
+            <div class="chart-wrapper">
+              <notice-chart />
+            </div>
           </div>
         </el-card>
       </el-col>
@@ -93,10 +67,11 @@
 
 <script>
 import BrithChart from "./dashboard/BrithChart";
+import NoticeChart from "./dashboard/NoticeChart";
 
 export default {
   name: "Index",
-  components: { BrithChart },
+  components: { BrithChart, NoticeChart },
   data() {
     return {
       urls: [

+ 154 - 2
ruoyi-ui/src/views/system/notice/index.vue

@@ -27,6 +27,9 @@
           />
         </el-select>
       </el-form-item>
+      <el-form-item label="归属部门" prop="deptId" style="width: 268px;">
+        <treeselect style="width: 200px;" v-model="queryParams.deptId" :options="deptOptions" :show-count="true" placeholder="请选择归属部门" />
+      </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@@ -77,7 +80,12 @@
         align="center"
         prop="noticeTitle"
         :show-overflow-tooltip="true"
-      />
+      >
+        <template slot-scope="scope">
+          <el-tag type="success" v-if="scope.row.isPinned == 1">已置顶</el-tag>
+          {{scope.row.noticeTitle}}
+        </template>
+      </el-table-column>
       <el-table-column label="公告类型" align="center" prop="noticeType" width="100">
         <template slot-scope="scope">
           <dict-tag :options="dict.type.sys_notice_type" :value="scope.row.noticeType"/>
@@ -96,6 +104,28 @@
       </el-table-column>
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-select"
+            @click="handlePin (scope.row)"
+            v-if="scope.row.isPinned == 0"
+            v-hasPermi="['system:notice:edit']"
+          >置顶</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-select"
+            @click="handlePin (scope.row)"
+            v-if="scope.row.isPinned == 1"
+            v-hasPermi="['system:notice:edit']"
+          >取消置顶</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-select"
+            @click="handleSelect (scope.row)"
+          >查看</el-button>
           <el-button
             size="mini"
             type="text"
@@ -143,7 +173,12 @@
               </el-select>
             </el-form-item>
           </el-col>
-          <el-col :span="24">
+          <el-col :span="12">
+            <el-form-item label="归属部门" prop="deptId">
+              <treeselect v-model="form.deptId" :options="deptOptions" :show-count="true" placeholder="请选择归属部门"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
             <el-form-item label="状态">
               <el-radio-group v-model="form.status">
                 <el-radio
@@ -166,17 +201,70 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
+
+    <!-- 查看公告对话框 -->
+    <el-dialog v-dialogDrag :title="title" :visible.sync="checkView" width="780px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="公告标题" prop="noticeTitle">
+              <el-input v-model="form.noticeTitle" placeholder="请输入公告标题" v-bind:disabled="check"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="公告类型" prop="noticeType">
+              <el-select v-model="form.noticeType" placeholder="请选择公告类型" v-bind:disabled="check">
+                <el-option
+                  v-for="dict in typeOptions"
+                  :key="dict.dictValue"
+                  :label="dict.dictLabel"
+                  :value="dict.dictValue"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="状态">
+              <el-radio-group v-model="form.status">
+                <el-radio
+                  v-for="dict in statusOptions"
+                  :key="dict.dictValue"
+                  :label="dict.dictValue"
+                  v-bind:disabled="check"
+                >{{dict.dictLabel}}</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24" v-if="check">
+            <el-form-item label="内容">
+              <p v-html="form.noticeContent" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-dialog>
   </div>
 </template>
 
 <script>
 import { listNotice, getNotice, delNotice, addNotice, updateNotice } from "@/api/system/notice";
+import {treeselect} from "@/api/system/dept";
+import {getToken} from "@/utils/auth";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
 
 export default {
   name: "Notice",
+  components: { Treeselect },
   dicts: ['sys_notice_status', 'sys_notice_type'],
   data() {
     return {
+      // 类型数据字典
+      statusOptions: [],
+      // 状态数据字典
+      typeOptions: [],
+      checkView: false,
+      check: false,
       // 遮罩层
       loading: true,
       // 选中数组
@@ -212,14 +300,78 @@ export default {
         ],
         noticeType: [
           { required: true, message: "公告类型不能为空", trigger: "change" }
+        ],
+        deptId: [
+          { required: true, message: "归属类型不能为空", trigger: "change" }
         ]
       }
     };
   },
   created() {
     this.getList();
+    this.getTreeselect();
+    this.getDicts("sys_notice_status").then(response => {
+      this.statusOptions = response.data;
+    });
+    this.getDicts("sys_notice_type").then(response => {
+      this.typeOptions = response.data;
+    });
   },
   methods: {
+    /** 查询部门下拉树结构 */
+    getTreeselect() {
+      treeselect().then(response => {
+        this.deptOptions = response.data;
+      });
+    },
+    // 公告状态字典翻译
+    statusFormat(row, column) {
+      return this.selectDictLabel(this.statusOptions, row.status);
+    },
+    // 公告状态字典翻译
+    typeFormat(row, column) {
+      return this.selectDictLabel(this.typeOptions, row.noticeType);
+    },
+    /** 查看 **/
+    handleSelect(row) {
+      this.reset();
+      const noticeId = row.noticeId || this.ids
+      getNotice(noticeId).then(response => {
+        this.form = response.data;
+        this.checkView = true;
+        this.check= true;
+        this.title = '查看公告';
+      });
+    },
+    /** 处理置顶 */
+    handlePin(row) {
+      let notice = row;
+      if (notice.isPinned == 0) {
+        this.$confirm('是否确认置顶公告编号为 '+ ' '+notice.noticeId+ ' 的数据项?', '警告', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          notice.isPinned = 1;
+          updateNotice(notice).then(() => {
+            this.$modal.msgSuccess('置顶成功');
+            this.getList();
+          });
+        })
+      } else {
+        this.$confirm('是否确认取消置顶公告编号为 '+ ' '+notice.noticeId+ ' 的数据项?', '警告', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          notice.isPinned = 0;
+          updateNotice(notice).then(() => {
+            this.$modal.msgSuccess('取消置顶成功');
+            this.getList();
+          });
+        })
+      }
+    },
     /** 查询公告列表 */
     getList() {
       this.loading = true;