基于springboot数码论坛系统源码和论文

news2024/11/16 13:55:53

网络的广泛应用给生活带来了十分的便利。所以把数码论坛与现在网络相结合,利用java技术建设数码论坛系统,实现数码论坛的信息化。则对于进一步提高数码论坛发展,丰富数码论坛经验能起到不少的促进作用。

数码论坛系统能够通过互联网得到广泛的、全面的宣传,让尽可能多的用户了解和熟知数码论坛系统的便捷高效,不仅为用户提供了服务,而且也推广了自己,让更多的用户了解自己。对于数码论坛而言,若拥有自己的系统,通过系统得到更好的管理,同时提升了形象。

系统设计的现状和趋势,从需求、结构、数据库等方面的设计到系统的实现,分别为管理员和用户实现。论文的内容从系统的设计、描述、实现、分析、测试方面来表明开发的过程。本系统根据现实情况来选择一种可行的开发方案,借助java编程语言和MySQL数据库等实现系统的全部功能,接下来对系统进行测试,测试系统是否有漏洞和测试用户权限来完善系统最终系统完成达到相关标准。

基于springboot数码论坛系统源码和论文323

关键字:数码论坛系统 java  MySQL数据库

演示视频:

基于springboot数码论坛系统源码和论文

Abstract

The wide application of network has brought great convenience to life. So the digital forum and the current network combined, using Java technology to build a digital forum system, digital forum information. It can further improve the development of digital forum and enrich the experience of digital forum.

Digital forum system can be widely and comprehensively publicized through the Internet, so that as many users as possible understand and be familiar with the convenient and efficient digital forum system, not only to provide services for users, but also to promote themselves, so that more users understand themselves. For digital forums, if they have their own system, they can get better management through the system and improve their image.

The present situation and trend of the system design, from the requirements, structure, database and other aspects of the design to the realization of the system, respectively for the realization of administrators and users. The content of the paper shows the development process from the aspects of system design, description, implementation, analysis and testing. The system according to the reality to choose a feasible development plan, with the help of Java programming language and MySQL database to achieve all the functions of the system, then the system is tested, test whether the system has vulnerabilities and test user permissions to improve the system, the final system to achieve relevant standards.

Keywords: digital forum system Java MySQL database

package com.controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.annotation.IgnoreAuth;
import com.baidu.aip.face.AipFace;
import com.baidu.aip.face.MatchRequest;
import com.baidu.aip.util.Base64Util;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.entity.ConfigEntity;
import com.service.CommonService;
import com.service.ConfigService;
import com.utils.BaiduUtil;
import com.utils.FileUtil;
import com.utils.R;
/**
 * 通用接口
 */
@RestController
public class CommonController{
	@Autowired
	private CommonService commonService;

    private static AipFace client = null;
    
    @Autowired
    private ConfigService configService;    
	/**
	 * 获取table表中的column列表(联动接口)
	 * @param table
	 * @param column
	 * @return
	 */
	@IgnoreAuth
	@RequestMapping("/option/{tableName}/{columnName}")
	public R getOption(@PathVariable("tableName") String tableName, @PathVariable("columnName") String columnName,String level,String parent) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("table", tableName);
		params.put("column", columnName);
		if(StringUtils.isNotBlank(level)) {
			params.put("level", level);
		}
		if(StringUtils.isNotBlank(parent)) {
			params.put("parent", parent);
		}
		List<String> data = commonService.getOption(params);
		return R.ok().put("data", data);
	}
	
	/**
	 * 根据table中的column获取单条记录
	 * @param table
	 * @param column
	 * @return
	 */
	@IgnoreAuth
	@RequestMapping("/follow/{tableName}/{columnName}")
	public R getFollowByOption(@PathVariable("tableName") String tableName, @PathVariable("columnName") String columnName, @RequestParam String columnValue) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("table", tableName);
		params.put("column", columnName);
		params.put("columnValue", columnValue);
		Map<String, Object> result = commonService.getFollowByOption(params);
		return R.ok().put("data", result);
	}
	
	/**
	 * 修改table表的sfsh状态
	 * @param table
	 * @param map
	 * @return
	 */
	@RequestMapping("/sh/{tableName}")
	public R sh(@PathVariable("tableName") String tableName, @RequestBody Map<String, Object> map) {
		map.put("table", tableName);
		commonService.sh(map);
		return R.ok();
	}
	
	/**
	 * 获取需要提醒的记录数
	 * @param tableName
	 * @param columnName
	 * @param type 1:数字 2:日期
	 * @param map
	 * @return
	 */
	@IgnoreAuth
	@RequestMapping("/remind/{tableName}/{columnName}/{type}")
	public R remindCount(@PathVariable("tableName") String tableName, @PathVariable("columnName") String columnName, 
						 @PathVariable("type") String type,@RequestParam Map<String, Object> map) {
		map.put("table", tableName);
		map.put("column", columnName);
		map.put("type", type);
		
		if(type.equals("2")) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar c = Calendar.getInstance();
			Date remindStartDate = null;
			Date remindEndDate = null;
			if(map.get("remindstart")!=null) {
				Integer remindStart = Integer.parseInt(map.get("remindstart").toString());
				c.setTime(new Date()); 
				c.add(Calendar.DAY_OF_MONTH,remindStart);
				remindStartDate = c.getTime();
				map.put("remindstart", sdf.format(remindStartDate));
			}
			if(map.get("remindend")!=null) {
				Integer remindEnd = Integer.parseInt(map.get("remindend").toString());
				c.setTime(new Date());
				c.add(Calendar.DAY_OF_MONTH,remindEnd);
				remindEndDate = c.getTime();
				map.put("remindend", sdf.format(remindEndDate));
			}
		}
		
		int count = commonService.remindCount(map);
		return R.ok().put("count", count);
	}
	
	/**
	 * 单列求和
	 */
	@IgnoreAuth
	@RequestMapping("/cal/{tableName}/{columnName}")
	public R cal(@PathVariable("tableName") String tableName, @PathVariable("columnName") String columnName) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("table", tableName);
		params.put("column", columnName);
		Map<String, Object> result = commonService.selectCal(params);
		return R.ok().put("data", result);
	}
	
	/**
	 * 分组统计
	 */
	@IgnoreAuth
	@RequestMapping("/group/{tableName}/{columnName}")
	public R group(@PathVariable("tableName") String tableName, @PathVariable("columnName") String columnName) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("table", tableName);
		params.put("column", columnName);
		List<Map<String, Object>> result = commonService.selectGroup(params);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		for(Map<String, Object> m : result) {
			for(String k : m.keySet()) {
				if(m.get(k) instanceof Date) {
					m.put(k, sdf.format((Date)m.get(k)));
				}
			}
		}
		return R.ok().put("data", result);
	}
	
	/**
	 * (按值统计)
	 */
	@IgnoreAuth
	@RequestMapping("/value/{tableName}/{xColumnName}/{yColumnName}")
	public R value(@PathVariable("tableName") String tableName, @PathVariable("yColumnName") String yColumnName, @PathVariable("xColumnName") String xColumnName) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("table", tableName);
		params.put("xColumn", xColumnName);
		params.put("yColumn", yColumnName);
		List<Map<String, Object>> result = commonService.selectValue(params);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		for(Map<String, Object> m : result) {
			for(String k : m.keySet()) {
				if(m.get(k) instanceof Date) {
					m.put(k, sdf.format((Date)m.get(k)));
				}
			}
		}
		return R.ok().put("data", result);
	}

	/**
 	 * (按值统计)时间统计类型
	 */
	@IgnoreAuth
	@RequestMapping("/value/{tableName}/{xColumnName}/{yColumnName}/{timeStatType}")
	public R valueDay(@PathVariable("tableName") String tableName, @PathVariable("yColumnName") String yColumnName, @PathVariable("xColumnName") String xColumnName, @PathVariable("timeStatType") String timeStatType) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("table", tableName);
		params.put("xColumn", xColumnName);
		params.put("yColumn", yColumnName);
		params.put("timeStatType", timeStatType);
		List<Map<String, Object>> result = commonService.selectTimeStatValue(params);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		for(Map<String, Object> m : result) {
			for(String k : m.keySet()) {
				if(m.get(k) instanceof Date) {
					m.put(k, sdf.format((Date)m.get(k)));
				}
			}
		}
		return R.ok().put("data", result);
	}
	
    /**
     * 人脸比对
     * 
     * @param face1 人脸1
     * @param face2 人脸2
     * @return
     */
    @RequestMapping("/matchFace")
    @IgnoreAuth
    public R matchFace(String face1, String face2,HttpServletRequest request) {
        if(client==null) {
            /*String AppID = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "AppID")).getValue();*/
            String APIKey = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "APIKey")).getValue();
            String SecretKey = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "SecretKey")).getValue();
            String token = BaiduUtil.getAuth(APIKey, SecretKey);
            if(token==null) {
                return R.error("请在配置管理中正确配置APIKey和SecretKey");
            }
            client = new AipFace(null, APIKey, SecretKey);
            client.setConnectionTimeoutInMillis(2000);
            client.setSocketTimeoutInMillis(60000);
        }
        JSONObject res = null;
        try {
            File path = new File(ResourceUtils.getURL("classpath:static").getPath());
            if(!path.exists()) {
                path = new File("");
            }
            File upload = new File(path.getAbsolutePath(),"/upload/");
            File file1 = new File(upload.getAbsolutePath()+"/"+face1);
            File file2 = new File(upload.getAbsolutePath()+"/"+face2);
            String img1 = Base64Util.encode(FileUtil.FileToByte(file1));
            String img2 = Base64Util.encode(FileUtil.FileToByte(file2));
            MatchRequest req1 = new MatchRequest(img1, "BASE64");
            MatchRequest req2 = new MatchRequest(img2, "BASE64");
            ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>();
            requests.add(req1);
            requests.add(req2);
            res = client.match(requests);
            System.out.println(res.get("result"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return R.error("文件不存在");
        } catch (IOException e) {
            e.printStackTrace();
        } 
        return R.ok().put("score", com.alibaba.fastjson.JSONObject.parse(res.getJSONObject("result").get("score").toString()));
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.jlwl</groupId>
	<!-- 导入项目的名称 -->
	<artifactId>springboot1f60t</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springboot-schema</name>
	<description>springboot学习框架</description>

	<properties>
		<java.version>1.8</java.version>
		<fastjson.version>1.2.8</fastjson.version>
		<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.1.1</version>
		</dependency>
		<dependency>
		    <groupId>org.springframework.boot</groupId>
		    <artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		
		<dependency>
		    <groupId>mysql</groupId>
		    <artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>1.3.2</version>
		</dependency>
		
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus</artifactId>
			<version>2.3</version>
		</dependency>
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatisplus-spring-boot-starter</artifactId>
			<version>1.0.5</version>
		</dependency>
		<dependency>
		    <groupId>com.google.protobuf</groupId>
		    <artifactId>protobuf-java</artifactId>
		    <version>3.10.0</version>
		</dependency>
		
		<dependency>
		    <groupId>org.apache.commons</groupId>
		    <artifactId>commons-lang3</artifactId>
		    <version>3.0</version>
		</dependency>
		
		<dependency>
		    <groupId>javax.validation</groupId>
		    <artifactId>validation-api</artifactId>
		    <version>2.0.1.Final</version>
		</dependency>
		
		<dependency>
		    <groupId>commons-io</groupId>
		    <artifactId>commons-io</artifactId>
		    <version>2.5</version>
		</dependency>
		
		
		<dependency>
		    <groupId>cn.hutool</groupId>
		    <artifactId>hutool-all</artifactId>
		    <version>4.0.12</version>
		</dependency>
		
		<!-- FastJson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>${fastjson.version}</version>
		</dependency>
		<dependency>
		    <groupId>com.microsoft.sqlserver</groupId>
		    <artifactId>sqljdbc4</artifactId>
		    <scope>4.0</scope>
		    <version>4.0</version>
		</dependency>
		
		<dependency>
		    <groupId>com.microsoft.sqlserver</groupId>
		    <artifactId>mssql-jdbc</artifactId>
		    <version>6.2.0.jre8</version>
		    <scope>runtime</scope>
		</dependency>
		<!-- 百度人工智能 -->
		<dependency>
    		<groupId>com.baidu.aip</groupId>
    		<artifactId>java-sdk</artifactId>
    		<version>4.4.1</version>
		</dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.11</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.9</version>
        </dependency>

		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1387433.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大语言模型系列-总述

大语言模型发展史 研究人员发现&#xff0c;扩展预训练模型&#xff08;Pre-training Language Model&#xff0c;PLM&#xff09;&#xff0c;例如扩展模型大小或数据大小&#xff0c;通常会提高下游任务的模型性能&#xff0c;模型大小从几十亿&#xff08;1 B 10亿&#x…

细说JavaScript对象(JavaScript对象详解)

在JavaScript中对象作为数据类型之一&#xff0c;它的数据结构区别于其余5中数据类型&#xff0c;从数据结构角度看对象就是数据值的几个&#xff0c;其书就结构就是若干组名值对&#xff0c;类似于其他语言中的哈希、散列 关联数组等&#xff0c;但对象在JavaScript中不仅仅扮…

【MySQL高级】——InnoDB数据存储结构

1. 数据库的存储结构&#xff1a;页 <1> 磁盘与内存交互的基本单位&#xff1a;页 <2> 页结构概述 <3> 页的大小 <4> 页的上层结构 2. 页的内部结构 <1> 页的分类 <2> 页的结构 <3> File Header&#xff08;文件头&#xff09; 1.…

AUTO SEG-LOSS SEARCHING METRIC SURROGATES FOR SEMANTIC SEGMENTATION

AUTO SEG-LOSS: 搜索度量替代语义分割 论文链接&#xff1a;https://arxiv.org/abs/2010.07930 项目链接&#xff1a;https://github.com/fundamentalvision/Auto-Seg-Loss ABSTRACT 设计合适的损失函数是训练深度网络的关键。特别是在语义分割领域&#xff0c;针对不同的场…

Nginx安装http2和ssl模块

Nginx安装http2和ssl模块 Nginx在执行默认安装命令的时候&#xff0c;并不会编译启用ngx_http_v2_module模块。故在修改Nginx配置文件启用http2.0协议的时候会报错。 一.检查Nginx安装了哪些模块 #进入Nginx的安装目录 cd /usr/local/nginx #执行命令查看安装了哪些模块 ./sbi…

腾讯云服务器定价_云服务器价格_云服务器计费模式

腾讯云服务器租用价格表&#xff1a;轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;2核4G5M带宽756元三年、轻量4核8G12M服务器446元一年、646元15个月&#xff0c;云服务器CVM S5实例2核2G配置280.8元一年…

java基本类型与包装类型之间的关系

JAVA基本类型和包装类型 前言 Java语言中的数据类型分为基本数据类型和引用类型&#xff0c;而我们进行Java开发的时候都听说过基本数据类型和包装类型&#xff0c;今天我们就来详细聊一聊Java中的基本数据类型和包装类型之间的区别。 基本数据类型 Java中的基本数据类型一共有…

2024腾讯云服务器购买指南一步步全流程攻略(超详细)

腾讯云服务器购买流程很简单&#xff0c;有两种购买方式&#xff0c;直接在官方活动上购买比较划算&#xff0c;在云服务器CVM或轻量应用服务器页面自定义购买价格比较贵&#xff0c;但是自定义购买云服务器CPU内存带宽配置选择范围广&#xff0c;活动上购买只能选择固定的活动…

运筹说 第80期 | 最小费用最大流问题

前面我们学习了图与网络分析的基础知识及经典问题&#xff0c;大家是否已经学会了呢&#xff1f;接下来小编和大家学习最后一个经典问题——最小费用最大流问题。 最小费用最大流问题是经济学和管理学中的一类典型问题。在一个网络中每段路径都有“容量”和“费用”两个限制的…

微软Office 2021 批量许可版

软件介绍 微软办公软件套件Microsoft Office LTSC 2021 专业增强版2024年1月批量许可版更新推送&#xff01;Office2021正式版和Windows11系统同时于2021年10月份正式推出&#xff0c;Office LTSC 2021相比 Office2019正式版变化不太&#xff0c;最主要强化了LOGO设计趋势&…

运维必存的20个常见的故障排查、修复大全

你们好&#xff0c;我的网工朋友。 “稳定是偶然&#xff0c;异常才是常态”。这句话用来形容运维的工作再合适不过了 对于运维来说&#xff0c;工作最常遇到的就是不稳定性带来的各种故障&#xff0c;经常围绕发现故障、响应故障、定位故障、恢复故障这四大步骤打转。 为此…

mysql高级使用教程

mysql体系结构 1.连接层&#xff1a;主要就是做客户端的连接。 2.服务层&#xff1a;主要就是 缓存&#xff0c;分析器&#xff0c;优化器&#xff0c;执行器。 3.引擎层&#xff1a;就是一些存储引擎&#xff0c;包括索引的存储结构。 4.存储层&#xff1a;数据存储的磁盘…

CSS实现超出部分的省略

1、为什么要省略 在日常开发过程中我们难免会遇到后端返回给我们的的数据太长的情况&#xff0c;此时我们通常采取的是...的省略方式&#xff0c;其中的CSS大致如下&#xff0c;既可以实现对应的省略显示&#xff0c;但有些时候我们有需要用户可以查看具体的完整信息&#xff0…

内网yum仓库 ftp;http方式

ftp方式 服务端 客户端 vim /etc/yum.repos.d/ftp.repo http方式 服务端 yum install httpd -y systemctl start httpd cd /var/www/html/ mkdir centos7 mount /dev/sr0 /var/www/html/centos7 客户端

*(长期更新)软考网络工程师学习笔记——Section 22 无线局域网

目录 一、IEEE 802.11的定义二、IEEE 802.11系列标准三、IEEE 802.11的两种工作模式四、CDMA/CA协议&#xff08;一&#xff09;CDMA/CA协议的定义&#xff08;二&#xff09;CDMA/CA协议的过程 五、AC与AP&#xff08;一&#xff09;接入控制器AC&#xff08;二&#xff09;无…

go的安装及配置

go的官方下载地址&#xff1a;All releases - The Go Programming Language​​​​​​ 1、找到对应的版本包下载&#xff0c;例如 wget https://golang.google.cn/dl/go1.21.6.linux-amd64.tar.gz 2、下载完成后配置解压Go源码包 tar -zxf go1.21.6.linux-amd64.tar.gz 3…

32 二叉树的定义

之前的通用树结构 采用双亲孩子表示法模型 孩子兄弟表示法模型 引出二叉树 二叉树的定义&#xff1a; 满二叉树和完全二叉树 对此图要有印象 满二叉树一定是完全二叉树&#xff0c;但是完全二叉树不一定是满二叉树 小结

博客摘录「 性能优化:__builtin_expect详解」2024年1月15日

性能优化&#xff1a;__builtin_expect详解___builtin_expect对性能的影响-CSDN博客https://blog.csdn.net/chudongfang2015/article/details/75710848 #define LIKELY(x) __builtin_expect(!!(x), 1) __builtin_expect宏定义中为何写成!!(x)&#xff1f; 首先__buildin_expec…

buuctf-Misc 题目解答分解118-120

118.[INSHack2017]sanity 打开压缩包就是一个md 文件 typora 打开 发现flag INSA{Youre_sane_Good_for_you} 119.粽子的来历 解压压缩包 &#xff0c;得到文件夹如下 用010 editor 打开 我是A.doc 这个有些可以 都改成FF 保存 然后再次打开 docx 文件就发现了屈原的诗 其他b…

雍禾医疗好医生:雍禾植发张华医生立志服务好毛发患者

作为中国领先的专门从事毛发医疗服务的医疗集团&#xff0c;雍禾医疗提供诊疗、植发、养固等一站式毛发医疗服务&#xff0c;旗下拥有由专业植发品牌“雍禾植发”、医疗养固品牌“史云逊”、女性美学植发品牌“雍禾发之初”及医学假发品牌“哈发达”等组成的全产业链品牌矩阵。…