From d11f94ca0610417a7c6fc634925e85e28972224c Mon Sep 17 00:00:00 2001
From: zxl <763096477@qq.com>
Date: 星期二, 24 六月 2025 14:16:34 +0800
Subject: [PATCH] 新闻管理
---
manager/src/views/news/index.vue | 543 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
manager/src/api/news.js | 39 +++
2 files changed, 582 insertions(+), 0 deletions(-)
diff --git a/manager/src/api/news.js b/manager/src/api/news.js
new file mode 100644
index 0000000..19aca4e
--- /dev/null
+++ b/manager/src/api/news.js
@@ -0,0 +1,39 @@
+import service from "../libs/axios";
+
+export const getNews = (params) =>{
+ return service({
+ url: "/news/page",
+ method: "GET",
+ params: params
+ })
+}
+
+export const addNews = (params) =>{
+ return service({
+ url: "/news",
+ method: "POST",
+ data: params
+ })
+}
+
+export const editNews = (params) =>{
+ return service({
+ url: "/news",
+ method: "PUT",
+ data: params
+ })
+}
+
+export const publish = (param) =>{
+ return service({
+ url: "/news/publish/"+ param,
+ method: "PUT",
+ })
+}
+
+export const delById = (param) =>{
+ return service({
+ url: "/news/"+ param,
+ method: "DELETE",
+ })
+}
diff --git a/manager/src/views/news/index.vue b/manager/src/views/news/index.vue
new file mode 100644
index 0000000..e9d2d95
--- /dev/null
+++ b/manager/src/views/news/index.vue
@@ -0,0 +1,543 @@
+<template>
+ <div class="news-management">
+ <Card>
+ <!-- 鎼滅储琛ㄥ崟 -->
+ <Form
+ ref="searchForm"
+ @keydown.enter.native="handleSearch"
+ :model="searchForm"
+ inline
+ :label-width="80"
+ class="search-form"
+ >
+ <FormItem label="鏍囬" prop="title">
+ <Input
+ type="text"
+ v-model="searchForm.title"
+ placeholder="璇疯緭鍏ユ爣棰樺悕绉�"
+ clearable
+ @on-clear="handleSearch"
+ style="width: 180px"
+ />
+ </FormItem>
+ <FormItem label="鏄惁鍙戝竷" prop="publish">
+ <Select
+ v-model="searchForm.publish"
+ placeholder="璇烽�夋嫨"
+ style="width: 180px"
+ clearable
+ @on-clear="handleSearch"
+ @on-change="handleSearch"
+ >
+ <Option
+ v-for="item in typeSelect"
+ :value="item.value"
+ :key="item.id"
+ >
+ {{ item.label }}
+ </Option>
+ </Select>
+ </FormItem>
+ <Button
+ @click="handleSearch"
+ type="primary"
+ icon="ios-search"
+ class="search-btn"
+ >鎼滅储</Button>
+ <Button
+ @click="resetSearch"
+ icon="md-refresh"
+ style="margin-left: 8px"
+ >閲嶇疆</Button>
+ </Form>
+
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <Row class="operation">
+ <Button @click="openAdd" type="primary" icon="md-add">鏂板娲诲姩</Button>
+ <Button @click="delBatch" type="error" icon="md-trash" :disabled="selectCount === 0">鎵归噺鍒犻櫎</Button>
+ </Row>
+
+ <!-- 娲诲姩琛ㄦ牸 -->
+ <Table
+ :loading="loading"
+ border
+ :columns="columns"
+ :data="newsList"
+ ref="table"
+ @on-selection-change="showSelect"
+ class="news-table"
+ >
+ <!-- 灏侀潰灞曠ず鎻掓Ы -->
+ <!-- 鎿嶄綔鎸夐挳鎻掓Ы -->
+ <template slot-scope="{ row }" slot="action">
+ <div class="action-btns">
+ <Button
+ type="primary"
+ size="small"
+ @click="changeStatus(row, row.publish ? '涓嬫灦' : '鍙戝竷')"
+ :loading="row.statusLoading"
+ >
+ {{ row.publish ? '涓嬫灦' : '鍙戝竷' }}
+ </Button>
+ <Button
+ type="info"
+ size="small"
+ @click="detail(row)"
+ >璇︽儏</Button>
+ <Button
+ type="info"
+ size="small"
+ @click="openEdit(row)"
+ >缂栬緫</Button>
+ <Button
+ type="error"
+ size="small"
+ @click="delById(row)"
+ >鍒犻櫎</Button>
+ </div>
+ </template>
+ </Table>
+
+ <!-- 鍒嗛〉 -->
+ <Row type="flex" justify="end" class="page-footer">
+ <Page
+ :current="searchForm.pageNumber"
+ :total="total"
+ :page-size="searchForm.pageSize"
+ @on-change="changePage"
+ @on-page-size-change="changePageSize"
+ :page-size-opts="[10, 20, 50]"
+ size="small"
+ show-total
+ show-elevator
+ show-sizer
+ ></Page>
+ </Row>
+
+ <!-- 鏂伴椈缂栬緫/鏂板妯℃�佹 -->
+ <Modal
+ v-model="modelShow"
+ :title="modelTitle"
+ @on-cancel="modelClose"
+ width="800"
+ :mask-closable="false"
+ >
+ <Form ref="form" :model="newsForm" :label-width="100" :rules="rules">
+ <Row :gutter="16">
+ <Col span="12">
+ <FormItem label="鏍囬" prop="title">
+ <Input
+ v-model="newsForm.title"
+ placeholder="璇疯緭鍏ユ爣棰樺悕绉�"
+ clearable
+ />
+ </FormItem>
+ </Col>
+ <Col span="24">
+ <FormItem label="鏂伴椈鍐呭锛�" prop="content">
+ <editor ref="editor" @input="getReason" />
+ </FormItem>
+ </Col>
+ </Row>
+ </Form>
+
+ <div slot="footer">
+ <Button @click="modelClose">鍙栨秷</Button>
+ <Button type="primary" :loading="submitLoading" @click="saveOrUpdate">鎻愪氦</Button>
+ </div>
+ </Modal>
+
+
+ <Modal
+ v-model="infoModelShow"
+ :title="modelTitle"
+ @on-cancel="infoModelClose"
+ width="800"
+ :mask-closable="false"
+ >
+ <div class="detail-container">
+ <Row :gutter="16">
+ <Col span="12">
+ <div class="detail-item">
+ <label>鏍囬锛�</label>
+ <span>{{ newsInfo.title || '-' }}</span>
+ </div>
+ </Col>
+ <Col span="12">
+ <div class="detail-item">
+ <label>鏄惁鍙戝竷锛�</label>
+ <span>{{newsInfo.publish ? '宸插彂甯�':'鏈彂甯�'}}</span>
+ </div>
+ </Col>
+
+ <Col span="12">
+ <div class="detail-item" v-if="newsInfo.publish">
+ <label>鍙戝竷鏃堕棿锛�</label>
+ <span>{{ newsInfo.publishDate}}</span>
+ </div>
+ </Col>
+ <Col span="24">
+ <div class="detail-item">
+ <label>鏂伴椈鍐呭锛�</label>
+ <div
+ class="news-content"
+ v-html="newsInfo.content || '鏃犲唴瀹�'"
+ ></div>
+ </div>
+ </Col>
+ </Row>
+ </div>
+
+ <div slot="footer">
+ <Button @click="infoModelClose">鍏抽棴</Button>
+ </div>
+ </Modal>
+
+
+ <!-- 鍥剧墖棰勮妯℃�佹 -->
+ <Modal v-model="previewVisible" title="鍥剧墖棰勮" footer-hide>
+ <img :src="previewImageUrl" style="width: 100%">
+ </Modal>
+ </Card>
+ </div>
+</template>
+<script>
+import Editor from '@/components/editor/index.vue'
+import { getNews,editNews,addNews,publish,delById } from '@/api/news.js'
+export default {
+ name: "newsManagement",
+ components: {Editor},
+ data(){
+ return{
+ // 鍥剧墖棰勮
+ previewVisible: false,
+ previewImageUrl: '',
+
+ modelShow:false,
+ modelTitle:'',
+ submitLoading:false,
+ infoModelShow:false,
+ //琛ㄥご
+ columns: [
+ {
+ type: 'selection',
+ width: 60,
+ align: 'center'
+ },
+ {
+ title: '鏍囬',
+ key: 'title',
+ minWidth: 120,
+ tooltip: true
+ },
+ {
+ title: '鍙戝竷',
+ key: 'publish',
+ width: 100,
+ align: 'center',
+ render: (h, params) => {
+ return h('Tag', {
+ props: {
+ color: params.row.publish ? 'green' : 'default'
+ }
+ }, params.row.publish ? '宸插彂甯�' : '鏈彂甯�')
+ }
+ },
+ {
+ title: '鍙戝竷鏃堕棿',
+ key: 'publishDate',
+ width: 300,
+ align: 'center',
+ render: (h, { row }) => {
+ // 濡傛灉 publishDate 涓� null 鎴� undefined锛屾樉绀� "鏈彂甯�"
+ if (row.publishDate == null) {
+ return h('span', { style: { color: '#999' } }, '鏆傛棤');
+ }
+ // 鍚﹀垯姝e父鏄剧ず鏃ユ湡
+ return h('span', row.publishDate);
+ },
+ },
+ {
+ title: '鎿嶄綔',
+ slot: 'action',
+ width: 280,
+ align: 'center',
+ fixed: 'right'
+ }
+ ],
+
+ newsList:[],
+ total:0,
+ newsForm:{
+ id:'',
+ title:'',
+ content:'',
+ publish:0,
+ },
+ newsInfo:{
+ title:'',
+ publish:false,
+ publishDate:'',
+ content:''
+ },
+ rules: {
+ title: [
+ { required: true, message: '璇疯緭鍏ユ爣棰�', trigger: 'blur' },
+ { max: 50, message: '闀垮害涓嶈兘瓒呰繃50涓瓧绗�', trigger: 'blur' }
+ ],
+ publish: [
+ { required: true, message: '璇烽�夋嫨鏄惁鍙戝竷', trigger: 'blur' },
+ ],
+ content: [
+ { required: true, message: '璇疯緭鍏ユ柊闂诲唴瀹�', trigger: 'blur' }
+ ]
+ },
+
+ selectList:[],
+ selectCount:0,
+
+ loading:false,
+
+ searchForm: {
+ title: '',
+ publish: 0,
+ pageNumber: 1,
+ pageSize: 10
+ },
+ typeSelect:[
+ {
+ id:1,
+ label:'鏈彂甯�',
+ value:0
+ },
+ {
+ id:2,
+ label:'宸插彂甯�',
+ value:1
+ }
+
+ ]
+ }
+ },
+ mounted() {
+ this.getNewsList();
+ },
+ methods:{
+ getNewsList(){
+ this.loading = true
+ getNews(this.searchForm).then(res =>{
+ this.loading = false
+ if (res.code === 200) {
+ // 涓烘瘡涓�琛屾坊鍔爈oading鐘舵��
+ this.newsList = res.data.map(item => ({
+ ...item,
+ }))
+ this.total = res.total
+ }
+ }).catch(() => {
+ this.loading = false
+ })
+ },
+ getReason(content) {
+ this.newsForm.content = content
+ },
+ saveOrUpdate(){
+ this.$refs.form.validate(valid => {
+ if (valid) {
+ this.submitLoading = true
+ const submitData = {
+ ...this.newsForm,
+ publish: this.newsForm.publish !== 0, // true 鈫� 1, false 鈫� 0
+ };
+ if (this.newsForm.id){
+ editNews(submitData).then(res => {
+ this.submitLoading = false
+ if (res.code === 200) {
+ this.$Message.success(res.msg)
+ this.modelClose()
+ this.getNewsList()
+ }
+ }).catch(() => {
+ this.submitLoading = false
+ })
+ }else {
+ addNews(submitData).then(res => {
+ this.submitLoading = false
+ if (res.code === 200) {
+ this.$Message.success(res.msg)
+ this.modelClose()
+ this.getNewsList()
+ }
+ }).catch(() => {
+ this.submitLoading = false
+ })
+ }
+
+ }
+ })
+ },
+ infoModelClose(){
+ this.infoModelShow = false;
+ },
+ modelClose(){
+ this.modelShow = false;
+ },
+ changePage(page) {
+ this.searchForm.pageNumber = page
+ this.getNewsList()
+ },
+ // 鏀瑰彉姣忛〉鏉℃暟
+ changePageSize(pageSize) {
+ this.searchForm.pageNumber = 1
+ this.searchForm.pageSize = pageSize
+ this.getNewsList()
+ },
+
+ delById(row){
+ delById(row.id).then(res =>{
+ if (res.code === 200){
+ this.$Message.success(res.msg);
+ this.getNewsList();
+ }
+
+ })
+ },
+ openEdit(row){
+ this.modelTitle = '淇敼鏂伴椈';
+ this.modelShow = true;
+ this.$refs.form.resetFields();
+ this.newsForm.title = row.title;
+ this.newsForm.content = row.content;
+ this.newsForm.id = row.id;
+ this.$refs.editor.setContent(this.newsForm.content)
+ },
+ openAdd(){
+ this.modelTitle = '鏂板鏂伴椈';
+ this.modelShow = true;
+ this.$refs.form.resetFields()
+ this.newsForm.id = '';
+
+ },
+ detail(row){
+ this.modelTitle = '娲诲姩璇︽儏'
+ this.infoModelShow = true
+ this.newsInfo = row
+ },
+ changeStatus(row,action){
+ row.statusLoading = true;
+
+ publish(row.id).then(res =>{
+ row.statusLoading = false
+ if (res.code === 200){
+ this.$Message.success(res.msg);
+ this.getNewsList();
+ }
+ }).catch(() => {
+ row.statusLoading = false
+ })
+ },
+ // 琛ㄦ牸閫夋嫨鍙樺寲
+ showSelect(selection) {
+ this.selectList = selection.map(item => item.id)
+ this.selectCount = selection.length
+ },
+
+ delBatch(){
+
+ },
+ handleSearch(type, value){
+ this.searchForm.pageNumber = 1
+ this.getNewsList()
+ },
+ resetSearch(){
+ this.$refs.searchForm.resetFields()
+ this.searchForm.pageNumber = 1
+ this.getNewsList()
+ },
+
+ }
+}
+</script>
+
+<style scoped lang="scss">
+.activity-management {
+ .search-form {
+ padding: 16px;
+ background: #f8f8f9;
+ border-radius: 4px;
+ margin-bottom: 16px;
+
+ .ivu-form-item {
+ margin-bottom: 16px;
+ margin-right: 16px;
+ }
+
+ .search-btn {
+ margin-left: 8px;
+ }
+ }
+}
+.detail-container {
+ padding: 16px;
+}
+
+.detail-item {
+ margin-bottom: 18px;
+ line-height: 1.5;
+
+ label {
+ display: inline-block;
+ width: 100px;
+ color: #666;
+ font-weight: bold;
+ vertical-align: top;
+ }
+
+ span {
+ display: inline-block;
+ width: calc(100% - 110px);
+ }
+}
+
+.news-content {
+ border: 1px solid #dcdee2;
+ border-radius: 4px;
+ padding: 12px;
+ min-height: 100px;
+ margin-top: 8px;
+}
+.news-table {
+ .media-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100px;
+
+ .thumbnail {
+ max-width: 100%;
+ max-height: 100%;
+ object-fit: contain;
+ cursor: pointer;
+ transition: all 0.3s;
+
+ &:hover {
+ transform: scale(1.05);
+ box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
+ }
+ }
+ }
+
+ .action-btns {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+
+ .ivu-btn {
+ margin: 4px;
+ font-size: 12px;
+ padding: 2px 6px;
+ min-width: 60px;
+ }
+ }
+}
+</style>
--
Gitblit v1.8.0