Spring Boot・微信小程序・MySQLによる衣類回収リサイクルプラットフォームの設計と実装

概要

消費の拡大に伴い、衣類の廃棄量は年々増加しており、資源の浪費と環境負荷が社会課題となっている。従来の回収方式では効率化と可視化が不十分であり、利用者と回収担当者のマッチングにも限界があった。本システムは、Spring Bootをバックエンドに、微信小程序をモバイル入口に、MySQLを永続化層に採用したB/Sアーキテクチャの衣類回収リサイクルプラットフォームである。利用者は微信から回収依頼を行い、付与されたポイントで景品と交換できる。管理者と回収担当者はWeb管理画面から注文の調整と進捗管理を行う。RESTful APIを介して安全かつ効率的にデータをやり取りする。

技術アーキテクチャ

  • バックエンド:Spring Boot、MyBatis、Spring Security(認証)、RESTful API
  • モバイルフロントエンド:微信小程序(WXML/WXSS/JavaScript)
  • 管理画面:Vue.js、Element UI
  • データベース:MySQL 8.0
  • ビルド・実行:Maven、Tomcat(組込み)

データベース設計

以下に主要な3テーブルを示す。

利用者情報テーブル

カラム名データ型説明
member_idBIGINT主キー、会員固有ID
wx_openidVARCHAR(64)微信アカウント連携用OpenID
nicknameVARCHAR(32)表示名
mobileVARCHAR(16)携帯電話番号
created_atDATETIME登録日時(自動生成)
pointsINT所持ポイント

回収依頼テーブル

カラム名データ型説明
request_idBIGINT主キー、回収依頼ID
member_idBIGINT依頼者ID
collector_idBIGINT回収担当者ID
categoryVARCHAR(32)衣類カテゴリ
statusVARCHAR(16)受付/配達中/完了/キャンセル
pickup_addrVARCHAR(128)回収先住所
created_atDATETIME依頼日時(自動生成)

ポイント交換テーブル

カラム名データ型説明
exchange_idBIGINT主キー、交換履歴ID
member_idBIGINT利用者ID
item_nameVARCHAR(64)交換景品名
consumed_pointsINT消ポイント
ship_statusVARCHAR(16)未発送/発送済/配達完了
exchanged_atDATETIME交換日時(自動生成)

API設計方針

バックエンドはリソースごとにURLを設計し、HTTPメソッドで操作を区別する。認証が不要なエンドポイントはアノテーションで明示し、JWTまたはセッショントークンを検証してから後続処理を実行する。レスポンスは統一されたJSON形式で返却し、コード例を以下に示す。

実装例

アプリケーション起動クラス

package com.recycling;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
@MapperScan(basePackages = "com.recycling.mapper")
public class RecyclingPlatformApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(RecyclingPlatformApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(RecyclingPlatformApplication.class);
    }
}

会員認証コントローラー

package com.recycling.controller;

import com.recycling.entity.MemberEntity;
import com.recycling.service.AuthTokenService;
import com.recycling.service.MemberService;
import com.recycling.util.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/api/members")
public class MemberController {

    @Autowired
    private MemberService memberService;

    @Autowired
    private AuthTokenService authTokenService;

    @PostMapping("/auth/login")
    public Response login(@RequestParam String account,
                          @RequestParam String password,
                          HttpServletRequest request) {
        MemberEntity member = memberService.findByAccount(account);
        if (member == null || !member.getPassword().equals(password)) {
            return Response.fail("アカウントまたはパスワードが正しくありません");
        }
        String token = authTokenService.createToken(
                member.getMemberId(), account, "member", "会員");
        return Response.ok(token);
    }

    @PostMapping("/auth/register")
    public Response register(@RequestBody MemberEntity member) {
        if (memberService.existsByAccount(member.getAccount())) {
            return Response.fail("既に存在するアカウントです");
        }
        member.setMemberId(System.currentTimeMillis());
        memberService.save(member);
        return Response.ok();
    }

    @PostMapping("/auth/logout")
    public Response logout(HttpServletRequest request) {
        request.getSession().invalidate();
        return Response.ok();
    }

    @GetMapping("/profile")
    public Response profile(HttpServletRequest request) {
        Long memberId = (Long) request.getSession().getAttribute("memberId");
        MemberEntity member = memberService.findById(memberId);
        return Response.ok(member);
    }
}

タグ: Spring Boot 微信小程序 MySQL vue.js Element UI

10月17日 12:27 投稿