Vue.js | お知らせ機能の追加と管理者用管理機能の実装

はじめに

今回、メールアカウント申請システムに「お知らせ機能」を実装しました。この機能により、利用者に重要なお知らせを迅速に共有でき、管理者はお知らせの作成や編集、削除を行えるようになりました。本記事では、実装したコードを交えて、機能の概要をご紹介します。


お知らせ機能の概要

お知らせ機能では以下の2つの主要コンポーネントを実装しました。

  1. 利用者向けお知らせ一覧
    ダッシュボードで利用者がお知らせをリスト形式で確認できるようにしました。お知らせは最新順に表示され、タイトル、内容、作成日時が確認できます。
  2. 管理者用お知らせ管理機能
    管理者専用の「お知らせ管理」ページを実装しました。このページでは以下の操作が可能です。
  • 新規お知らせの追加
  • 既存お知らせの編集
  • 不要なお知らせの削除

実装内容

1. データベースの構造

お知らせを保存するため、announcements テーブルを新たに作成しました。

CREATE TABLE announcements (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    content TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

2. バックエンドの実装

バックエンドにはお知らせ機能を処理する AnnouncementController を追加しました。主なメソッドは以下の通りです。

<?php

class AnnouncementController
{
    private $db;

    public function __construct()
    {
        $this->db = (new Database())->getPdo();
    }

    // 利用者向けお知らせ取得
    public function getAnnouncements()
    {
        try {
            $stmt = $this->db->prepare("SELECT id, title, content, created_at FROM announcements ORDER BY created_at DESC");
            $stmt->execute();
            $announcements = $stmt->fetchAll(PDO::FETCH_ASSOC);

            echo json_encode(['success' => true, 'announcements' => $announcements]);
        } catch (PDOException $e) {
            http_response_code(500);
            echo json_encode(['success' => false, 'message' => 'お知らせの取得に失敗しました。']);
        }
    }

    // 管理者用お知らせ一覧取得
    public function getAllAnnouncements()
    {
        session_start();
        $role = $_SESSION['user_role'] ?? '';

        if ($role !== 'admin') {
            http_response_code(403);
            echo json_encode(['success' => false, 'message' => '権限がありません。']);
            return;
        }

        try {
            $stmt = $this->db->query("SELECT * FROM announcements ORDER BY created_at DESC");
            $announcements = $stmt->fetchAll(PDO::FETCH_ASSOC);

            echo json_encode(['success' => true, 'announcements' => $announcements]);
        } catch (PDOException $e) {
            http_response_code(500);
            echo json_encode(['success' => false, 'message' => 'お知らせ一覧の取得に失敗しました。']);
        }
    }

    // お知らせの追加
    public function createAnnouncement()
    {
        $data = json_decode(file_get_contents('php://input'), true);

        $title = $data['title'] ?? '';
        $content = $data['content'] ?? '';

        if (!$title || !$content) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => 'タイトルと内容は必須です。']);
            return;
        }

        try {
            $stmt = $this->db->prepare("INSERT INTO announcements (title, content) VALUES (:title, :content)");
            $stmt->execute([':title' => $title, ':content' => $content]);

            echo json_encode(['success' => true, 'message' => 'お知らせを追加しました。']);
        } catch (PDOException $e) {
            http_response_code(500);
            echo json_encode(['success' => false, 'message' => 'お知らせの追加に失敗しました。']);
        }
    }

    // お知らせの編集
    public function updateAnnouncement()
    {
        $data = json_decode(file_get_contents('php://input'), true);

        $id = $data['id'] ?? null;
        $title = $data['title'] ?? '';
        $content = $data['content'] ?? '';

        if (!$id || !$title || !$content) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => 'すべての項目を入力してください。']);
            return;
        }

        try {
            $stmt = $this->db->prepare("UPDATE announcements SET title = :title, content = :content WHERE id = :id");
            $stmt->execute([':title' => $title, ':content' => $content, ':id' => $id]);

            echo json_encode(['success' => true, 'message' => 'お知らせを更新しました。']);
        } catch (PDOException $e) {
            http_response_code(500);
            echo json_encode(['success' => false, 'message' => 'お知らせの更新に失敗しました。']);
        }
    }

    // お知らせの削除
    public function deleteAnnouncement()
    {
        $data = json_decode(file_get_contents('php://input'), true);

        $id = $data['id'] ?? null;

        if (!$id) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => 'IDが必要です。']);
            return;
        }

        try {
            $stmt = $this->db->prepare("DELETE FROM announcements WHERE id = :id");
            $stmt->execute([':id' => $id]);

            echo json_encode(['success' => true, 'message' => 'お知らせを削除しました。']);
        } catch (PDOException $e) {
            http_response_code(500);
            echo json_encode(['success' => false, 'message' => 'お知らせの削除に失敗しました。']);
        }
    }
}

3. フロントエンドの実装

ダッシュボードでは、利用者向けのお知らせをリスト形式で表示します。

export default {
  template: `
    <div>
      <h2>ダッシュボード</h2>
      <h3>お知らせ</h3>
      <ul>
        <li v-for="announcement in announcements" :key="announcement.id">
          <h4>{{ announcement.title }}</h4>
          <p>{{ announcement.content }}</p>
          <span>{{ formatDate(announcement.created_at) }}</span>
        </li>
      </ul>
    </div>
  `,
  data() {
    return {
      announcements: [],
    };
  },
  methods: {
    async fetchAnnouncements() {
      try {
        const response = await fetch('/api/announcements');
        const data = await response.json();
        if (data.success) {
          this.announcements = data.announcements;
        } else {
          console.error('お知らせの取得に失敗:', data.message);
        }
      } catch (error) {
        console.error('エラー:', error);
      }
    },
    formatDate(dateString) {
      return new Date(dateString).toLocaleString();
    },
  },
  created() {
    this.fetchAnnouncements();
  },
};

管理者用のお知らせ管理ページでは、CRUD操作をモーダルで行えるようにしました。


おわりに

お知らせ機能の追加により、利用者への情報共有がスムーズになり、システム運用の効率が向上しました。また、管理者が手軽にお知らせを操作できるため、より柔軟な対応が可能となりました。今後はカテゴリ分けや通知の優先度設定など、さらなる機能拡充を検討しています。

コメント

タイトルとURLをコピーしました