当前位置: 首页 > article >正文

angular+nodejs问卷调查系统

说明:我计划用angular+mysql+nodejs,做一套问卷调查系统,
1.先设计数据库表,
2.然后添加模拟数据,
3.然后写几个查询方法
4.然后用nodejs写service服务,查询mysql数据
5.然后写contrller路由,指向调用service方法
6.在angular里面写http请求
7.拿到json数据,解析
8.把解析的数据,展示在angular界面上
效果图:
在这里插入图片描述

step1:mysql 建表,添加数据,写查询方法


-- 1. 问卷表
CREATE TABLE survey (
                        id INT PRIMARY KEY AUTO_INCREMENT,
                        title VARCHAR(255) NOT NULL,
                        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 2. 问题表(包含题型)
CREATE TABLE question (
                          id INT PRIMARY KEY AUTO_INCREMENT,
                          survey_id INT NOT NULL,
                          content TEXT NOT NULL,
                          type ENUM('single_choice', 'multiple_choice', 'text') NOT NULL,
                          FOREIGN KEY (survey_id) REFERENCES survey(id)
);
-- 3. 选项表(用于单选/多选题)
CREATE TABLE `option` (
                          id INT PRIMARY KEY AUTO_INCREMENT,
                          question_id INT NOT NULL,
                          content VARCHAR(255) NOT NULL,
                          FOREIGN KEY (question_id) REFERENCES question(id)
);
-- 4. 用户表
CREATE TABLE user (
                      id INT PRIMARY KEY AUTO_INCREMENT,
                      username VARCHAR(50) NOT NULL
);
-- 5. 答案表(统一存储所有类型答案)
CREATE TABLE answer (
                        id INT PRIMARY KEY AUTO_INCREMENT,
                        user_id INT NOT NULL,
                        question_id INT NOT NULL,
                        option_id INT DEFAULT NULL,
                        answer_text TEXT DEFAULT NULL,
                        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                        FOREIGN KEY (user_id) REFERENCES user(id),
                        FOREIGN KEY (question_id) REFERENCES question(id),
                        FOREIGN KEY (option_id) REFERENCES `option`(id)
);

-- 插入问卷
INSERT INTO survey (title) VALUES
                               ('消费者满意度调查'),
                               ('产品使用习惯调查');
-- 插入问题(前3题属于问卷1)
INSERT INTO question (survey_id, content, type) VALUES
                                                    (1, '您对产品的满意度如何?', 'single_choice'),
                                                    (1, '您通过哪些渠道了解我们?', 'multiple_choice'),
                                                    (1, '请提出改进建议', 'text'),
                                                    (2, '您每天使用产品的频率?', 'single_choice');
-- 插入选项(问题1有4个选项,问题2有4个选项,问题4有3个选项)
INSERT INTO `option` (question_id, content) VALUES
                                                (1, '非常满意'), (1, '满意'), (1, '一般'), (1, '不满意'),
                                                (2, '互联网广告'), (2, '朋友推荐'), (2, '社交媒体'), (2, '其他'),
                                                (4, '1-3次'), (4, '4-6次'), (4, '6次以上');
-- 插入用户
INSERT INTO user (username) VALUES
                                ('张三'), ('李四'), ('王五');
-- 插入答案(模拟不同用户的回答)
-- 用户1的回答
INSERT INTO answer (user_id, question_id, option_id, answer_text) VALUES
                                                                      (1, 1, 1, NULL),
                                                                      (1, 2, 5, NULL), (1, 2, 6, NULL),
                                                                      (1, 3, NULL, '增加更多功能');

INSERT INTO answer (user_id, question_id, option_id) VALUES
    (1, 4, 5);
-- 用户2的回答
INSERT INTO answer (user_id, question_id, option_id) VALUES
                                                         (2, 1, 2), (2, 2, 5), (2, 2, 7);
-- 用户3的回答
INSERT INTO answer (user_id, question_id, option_id, answer_text) VALUES
                                                                      (3, 1, 1, NULL),
                                                                      (3, 2, 6, NULL), (3, 2, 8, NULL),
                                                                      (3, 3, NULL, '服务态度很好');

# 1. 查询单选问题选项统计
SELECT
    o.content AS '选项内容',
    COUNT(a.id) AS '选择次数'
FROM question q
         JOIN `option` o ON q.id = o.question_id
         LEFT JOIN answer a ON o.id = a.option_id AND q.id = a.question_id
WHERE q.id = 1
GROUP BY o.id
ORDER BY COUNT(a.id) DESC;


# 2. 查询多选题选项统计
SELECT
    o.content AS '选项内容',
    COUNT(a.id) AS '被选次数'
FROM question q
         JOIN `option` o ON q.id = o.question_id
         LEFT JOIN answer a ON o.id = a.option_id AND q.id = a.question_id
WHERE q.id = 2  -- 查询问题ID=2的多选题
GROUP BY o.id
ORDER BY COUNT(a.id) DESC;

# 3. 查询文本题反馈内容
SELECT
    u.username AS '用户',
    a.answer_text AS '反馈内容'
FROM answer a
         JOIN user u ON a.user_id = u.id
WHERE a.question_id = 3;

# 4. 按问卷统计整体回答率


SELECT
    s.title AS '问卷标题',
    COUNT(DISTINCT CONCAT(a.user_id, '-', q.id)) AS '实际回答数',
    COUNT(DISTINCT q.id) * COUNT(DISTINCT u.id) AS '理论最大回答数',
    ROUND(
            COUNT(DISTINCT CONCAT(a.user_id, '-', q.id)) /
            (COUNT(DISTINCT q.id) * COUNT(DISTINCT u.id)) * 100,
            2
    ) AS '回答率(%)'
FROM survey s
         LEFT JOIN question q ON s.id = q.survey_id
         CROSS JOIN user u
         LEFT JOIN answer a ON q.id = a.question_id AND u.id = a.user_id
GROUP BY s.id;





# 5. 按用户统计答题记录
SELECT
    u.username AS '用户名',
    s.title AS '问卷标题',
    COUNT(DISTINCT a.question_id) AS '已答问题数',
    COUNT(DISTINCT q.id) AS '总问题数',
    ROUND(
            COUNT(DISTINCT a.question_id) /
            COUNT(DISTINCT q.id) * 100,
            2
    ) AS '完成率(%)'
FROM user u
         CROSS JOIN survey s
         LEFT JOIN question q ON s.id = q.survey_id
         LEFT JOIN answer a ON u.id = a.user_id AND q.id = a.question_id
GROUP BY u.id, s.id;


# 分割线


-- 1. 单选问题选项统计
SELECT
    `option`.content AS '选项内容',
    COUNT(answer.id) AS '选择次数'
FROM question
         JOIN `option` ON question.id = `option`.question_id
         LEFT JOIN answer
                   ON `option`.id = answer.option_id
                       AND question.id = answer.question_id
WHERE question.id = 1
GROUP BY `option`.id
ORDER BY COUNT(answer.id) DESC;
-- 2. 多选问题选项统计
SELECT
    `option`.content AS '选项内容',
    COUNT(answer.id) AS '被选次数'
FROM question
         JOIN `option` ON question.id = `option`.question_id
         LEFT JOIN answer
                   ON `option`.id = answer.option_id
                       AND question.id = answer.question_id
WHERE question.id = 2
GROUP BY `option`.id
ORDER BY COUNT(answer.id) DESC;
-- 3. 文本题反馈内容
SELECT
    user.username AS '用户',
    answer.answer_text AS '反馈内容'
FROM answer
         JOIN user ON answer.user_id = user.id
WHERE answer.question_id = 3;
-- 4. 按问卷统计回答率
SELECT
    survey.title AS '问卷标题',
    COUNT(DISTINCT CONCAT(answer.user_id, '-', question.id)) AS '实际回答数',
    COUNT(DISTINCT question.id) * COUNT(DISTINCT user.id) AS '理论最大回答数',
    ROUND(
            COUNT(DISTINCT CONCAT(answer.user_id, '-', question.id)) /
            (COUNT(DISTINCT question.id) * COUNT(DISTINCT user.id)) * 100,
            2
    ) AS '回答率(%)'
FROM survey
         LEFT JOIN question ON survey.id = question.survey_id
         CROSS JOIN user
         LEFT JOIN answer
                   ON question.id = answer.question_id
                       AND user.id = answer.user_id
GROUP BY survey.id;
-- 5. 按用户统计答题记录
SELECT
    user.username AS '用户名',
    survey.title AS '问卷标题',
    COUNT(DISTINCT answer.question_id) AS '已答问题数',
    COUNT(DISTINCT question.id) AS '总问题数',
    ROUND(
            COUNT(DISTINCT answer.question_id) /
            COUNT(DISTINCT question.id) * 100,
            2
    ) AS '完成率(%)'
FROM user
         CROSS JOIN survey
         LEFT JOIN question ON survey.id = question.survey_id
         LEFT JOIN answer
                   ON user.id = answer.user_id
                       AND question.id = answer.question_id
GROUP BY user.id, survey.id;

step2:service层查询数据库中表的数据
C:\Users\Administrator\WebstormProjects\untitled4\question-crud.js

const config = require('./db');
class SurveyCrudService {
  // [1] 查询单选题统计
  static async getSingleQuestionStats(questionId) {
    const [rows] = await config.query(`
      SELECT
        o.content AS option_content,
        COUNT(a.id) AS selection_count
      FROM question q
      JOIN \`option\` o ON q.id = o.question_id
      LEFT JOIN answer a ON o.id = a.option_id AND q.id = a.question_id
      WHERE q.id = ?
      GROUP BY o.id
      ORDER BY selection_count DESC
    `, [questionId]);
    return rows;
  }
  // [2] 查询多选题统计
  static async getMultipleQuestionStats(questionId) {
    const [rows] = await config.query(`
      SELECT
        o.content AS option_content,
        COUNT(a.id) AS selected_count
      FROM question q
      JOIN \`option\` o ON q.id = o.question_id
      LEFT JOIN answer a ON o.id = a.option_id AND q.id = a.question_id
      WHERE q.id = ?
      GROUP BY o.id
      ORDER BY selected_count DESC
    `, [questionId]);
    return rows;
  }
  // [3] 查询文本题反馈
  static async getTextFeedbacks(questionId) {
    const [rows] = await config.query(`
      SELECT
        u.username AS user,
        a.answer_text AS feedback_content
      FROM answer a
      JOIN user u ON a.user_id = u.id
      JOIN question q ON a.question_id = q.id
      WHERE q.type = 'text' AND q.id = ?
    `, [questionId]);
    return rows;
  }
  // [4] 查询问卷回答率
  static async getSurveyResponseRate(surveyId) {
    const [rows] = await config.query(`
      SELECT
        s.title AS survey_title,
        COUNT(DISTINCT CONCAT(a.user_id, '-', q.id)) AS actual_responses,
        COUNT(DISTINCT q.id) * COUNT(DISTINCT u.id) AS theoretical_max_responses,
        ROUND(
          COUNT(DISTINCT CONCAT(a.user_id, '-', q.id)) /
          (COUNT(DISTINCT q.id) * COUNT(DISTINCT u.id)) * 100,
          2
        ) AS response_rate
      FROM survey s
      LEFT JOIN question q ON s.id = q.survey_id
      CROSS JOIN user u
      LEFT JOIN answer a ON q.id = a.question_id AND u.id = a.user_id
      WHERE s.id = ?
      GROUP BY s.id
    `, [surveyId]);
    return rows[0] || {};
  }

  // [5] 查询用户答题记录
  static async getUserAnswerRecords(userId) {
    const [rows] = await config.query(`
      SELECT
        s.title AS survey_title,
        COUNT(DISTINCT a.question_id) AS answered_questions,
        COUNT(DISTINCT q.id) AS total_questions,
        ROUND(
          COUNT(DISTINCT a.question_id) /
          COUNT(DISTINCT q.id) * 100,
          2
        ) AS completion_rate
      FROM user u
      CROSS JOIN survey s
      LEFT JOIN question q ON s.id = q.survey_id
      LEFT JOIN answer a ON u.id = a.user_id AND q.id = a.question_id
      WHERE u.id = ?
      GROUP BY u.id, s.id
    `, [userId]);
    return rows;
  }


}
module.exports = SurveyCrudService;

step3:写controller路由,调用service层的方法
C:\Users\Administrator\WebstormProjects\untitled4\question-spring.js

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const crud = require('./question-crud');
const app = express();
app.use(bodyParser.json());
app.use(cors());
// [接口1] 单选题统计
app.get('/api/stats/single/:questionId', async (req, res) => {
  try {
    const data = await crud.getSingleQuestionStats(parseInt(req.params.questionId));
    res.json(data);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});
// [接口2] 多选题统计
app.get('/api/stats/multiple/:questionId', async (req, res) => {
  try {
    const data = await crud.getMultipleQuestionStats(parseInt(req.params.questionId));
    res.json(data);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});
// [接口3] 文本题反馈
app.get('/api/feedback/text/:questionId', async (req, res) => {
  try {
    const data = await crud.getTextFeedbacks(parseInt(req.params.questionId));
    res.json(data);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});
// [接口4] 问卷回答率
app.get('/api/stats/response-rate/:surveyId', async (req, res) => {
  try {
    const data = await crud.getSurveyResponseRate(parseInt(req.params.surveyId));
    res.json(data);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// [接口5] 用户答题记录
app.get('/api/user/records/:userId', async (req, res) => {
  try {
    const data = await crud.getUserAnswerRecords(parseInt(req.params.userId));
    res.json(data);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// 启动服务器
const PORT = process.env.PORT || 5500;
app.listen(PORT, () => {
  console.log(`🚀 Server running on port ${PORT}`);
});

step4:运行服务

PS C:\Users\Administrator\WebstormProjects\untitled4> node question-spring.js
🚀 Server running on port 5500

step5:在postman里面测试,

-- 1. 单选问题选项统计URL: GET http://localhost:5500/api/stats/single/1


[
    {
        "选项内容": "非常满意",
        "选择次数": 2
    },
    {
        "选项内容": "满意",
        "选择次数": 1
    },
    {
        "选项内容": "一般",
        "选择次数": 0
    },
    {
        "选项内容": "不满意",
        "选择次数": 0
    }
]


-- 2. 多选问题选项统计URL: GET http://localhost:5500/api/stats/multiple/2

[
    {
        "选项内容": "互联网广告",
        "被选次数": 2
    },
    {
        "选项内容": "朋友推荐",
        "被选次数": 2
    },
    {
        "选项内容": "社交媒体",
        "被选次数": 1
    },
    {
        "选项内容": "其他",
        "被选次数": 1
    }
]


-- 3. 文本题反馈内容URL: GET http://localhost:5500/api/feedback/text/3
[
    {
        "用户": "张三",
        "反馈内容": "增加更多功能"
    },
    {
        "用户": "王五",
        "反馈内容": "服务态度很好"
    }
]


-- 4. 按问卷统计回答率URL: GET http://localhost:5500/api/stats/response-rate/1

{
    "问卷标题": "消费者满意度调查",
    "实际回答数": 8,
    "理论最大回答数": 9,
    "回答率": "88.89"
}
 

-- 5. 按用户统计答题记录URL: GET http://localhost:5500/api/user/records/1

[
    {
        "问卷标题": "消费者满意度调查",
        "已答问题数": 3,
        "总问题数": 3,
        "完成率": "100.00"
    },
    {
        "问卷标题": "产品使用习惯调查",
        "已答问题数": 1,
        "总问题数": 1,
        "完成率": "100.00"
    }
]


step6:到这里,nodejs后端和mysql就写完了,接下来写angular前端展示

step7:接口返回的数据,用于json解析
C:\Users\Administrator\WebstormProjects\untitled4\src\app\question\survey.model.ts

export interface Survey {
  // 单题统计
  singleStats?: Array<{ option_content: string; selection_count: number }>;
  // 多选统计
  multipleStats?: Array<{ option_content: string; selected_count: number }>;
  // 文本反馈
  textFeedback?: Array<{ user: string; feedback_content: string }>;
  // 回答率
  responseRate?: {
    survey_title: string;
    actual_responses: number;
    theoretical_max_responses: number;
    response_rate: string;
  };
  // 用户记录
  userRecords?: Array<{
    survey_title: string;
    answered_questions: number;
    total_questions: number;
    completion_rate: string;
  }>;
}

/*
‌选项内容‌	option_content
‌选择次数‌	selection_count
‌被选次数‌	selected_count
‌用户‌	user
‌反馈内容‌	feedback_content
‌问卷标题‌	survey_title
‌实际回答数‌	actual_responses
‌理论最大回答数‌	theoretical_max_responses
‌回答率‌	response_rate
‌已答问题数‌	answered_questions
‌总问题数‌	total_questions
‌完成率‌	completion_rate
* */

step8:http服务,封装的api请求
C:\Users\Administrator\WebstormProjects\untitled4\src\app\question\survey.service.ts

// survey.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable({
  providedIn: 'root'
})
export class SurveyService {
  private baseUrl = 'http://localhost:5500/api';
  constructor(private http: HttpClient) { }
  getSingleStats() {
    return this.http.get(`${this.baseUrl}/stats/single/1`);
  }
  getMultipleStats() {
    return this.http.get(`${this.baseUrl}/stats/multiple/2`);
  }
  getTextFeedback() {
    return this.http.get(`${this.baseUrl}/feedback/text/3`);
  }
  getResponseRate() {
    return this.http.get(`${this.baseUrl}/stats/response-rate/1`);
  }
  getUserRecords() {
    return this.http.get(`${this.baseUrl}/user/records/1`);
  }
}

step9:C:\Users\Administrator\WebstormProjects\untitled4\src\app\question\question.component.ts

import { Component,OnInit } from '@angular/core';
import { SurveyService } from './survey.service';

import { Survey } from './survey.model';
import {MatCard, MatCardContent, MatCardHeader,MatCardModule} from '@angular/material/card';
import {
  MatCell,
  MatCellDef,
  MatColumnDef,
  MatHeaderCell,
  MatHeaderCellDef,
  MatHeaderRow, MatHeaderRowDef, MatRow, MatRowDef,
  MatTable
} from '@angular/material/table';
import {NgForOf, NgIf} from '@angular/common';
import {MatList, MatListItem} from '@angular/material/list';
import {MatChip, MatChipListbox} from '@angular/material/chips';
import {MatAccordion, MatExpansionPanel, MatExpansionPanelTitle,MatExpansionModule} from '@angular/material/expansion';

@Component({
  selector: 'app-question',
  imports: [
    MatCard,
    MatCardHeader,
    MatCardContent,
    MatTable,
    MatHeaderCell,
    NgIf,
    MatCardModule,
    MatCell,
    MatExpansionModule,
    MatHeaderCellDef,
    MatColumnDef,
    MatCellDef,
    MatHeaderRow,
    MatRow,
    MatList,
    MatListItem,
    MatChipListbox,
    MatChip,
    MatAccordion,
    MatExpansionPanel,
    MatExpansionPanelTitle,
    MatRowDef,
    MatHeaderRowDef,
    NgForOf
  ],
  templateUrl: './question.component.html',
  styleUrl: './question.component.css'
})
export class QuestionComponent implements OnInit {
  data: Survey = {};
  constructor(private surveyService: SurveyService) {}
  ngOnInit() {
    this.loadAllData();
  }
  private loadAllData() {
    this.surveyService.getSingleStats().subscribe(res =>{
      this.data.singleStats = res as any
      console.log('getSingleStats', res)
    });

    this.surveyService.getMultipleStats().subscribe(res =>{
      this.data.multipleStats = res as any
      console.log('getMultipleStats', res)
    });

    this.surveyService.getTextFeedback().subscribe(res =>{
      console.log('getTextFeedback', res)
      this.data.textFeedback = res as any
    });

    this.surveyService.getResponseRate().subscribe(res =>{
      console.log('getResponseRate', res)
      this.data.responseRate = res as any
    });

    this.surveyService.getUserRecords().subscribe(res =>{
      console.log('getUserRecords', res)
      this.data.userRecords = res as any
    });
  }
}

step10:C:\Users\Administrator\WebstormProjects\untitled4\src\app\question\question.component.html


<!-- survey.component.html -->
<div class="dashboard-container">
  <!-- 响应率卡片 -->
  <mat-card *ngIf="data.responseRate" class="response-rate">
    <mat-card-header>
      <mat-card-title>{{ data.responseRate.survey_title }}</mat-card-title>
    </mat-card-header>
    <mat-card-content>
      <p>回答率: {{ data.responseRate.response_rate }}%</p>
      <p>实际回答数 / 最大回答数: {{ data.responseRate.actual_responses }} / {{ data.responseRate.theoretical_max_responses	 }}</p>
    </mat-card-content>
  </mat-card>
  <!-- 用户记录表格 -->
  <mat-table *ngIf="data.userRecords" [dataSource]="data.userRecords" class="user-records">
    <ng-container matColumnDef="问卷标题">
      <mat-header-cell *matHeaderCellDef> 问卷标题 </mat-header-cell>
      <mat-cell *matCellDef="let record"> {{ record.survey_title }} </mat-cell>
    </ng-container>
    <ng-container matColumnDef="完成率">
      <mat-header-cell *matHeaderCellDef> 完成率 </mat-header-cell>
      <mat-cell *matCellDef="let record"> {{ record.completion_rate }}% </mat-cell>
    </ng-container>
    <mat-header-row *matHeaderRowDef="['问卷标题', '完成率']"></mat-header-row>
    <mat-row *matRowDef="let row; columns: ['问卷标题', '完成率'];"></mat-row>
  </mat-table>
  <!-- 单选题统计 -->
  <mat-card *ngIf="data.singleStats">
    <h3>单选题统计</h3>
    <mat-list>
      <mat-list-item *ngFor="let item of data.singleStats">
        {{ item.option_content }}: {{ item.selection_count }}次
      </mat-list-item>
    </mat-list>
  </mat-card>
  <!-- 多选题统计 -->
  <mat-card *ngIf="data.multipleStats">
    <h3>多选题统计</h3>
    <mat-chip-listbox>
      <mat-chip *ngFor="let item of data.multipleStats">
        {{ item.option_content }} ({{ item.selected_count }})
      </mat-chip>
    </mat-chip-listbox>
  </mat-card>
  <!-- 文本反馈 -->
  <mat-card *ngIf="data.textFeedback">
    <h3>用户反馈</h3>
    <mat-accordion>
      <mat-expansion-panel *ngFor="let feedback of data.textFeedback">
        <mat-expansion-panel-header>
          <mat-panel-title>{{ feedback.user }}</mat-panel-title>
        </mat-expansion-panel-header>
        <p>{{ feedback.feedback_content }}</p>
      </mat-expansion-panel>
    </mat-accordion>
  </mat-card>
</div>

step11: C:\Users\Administrator\WebstormProjects\untitled4\src\app\question\question.component.css

.dashboard-container {
  padding: 20px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
  mat-card {
    margin-bottom: 20px;
    h3 {
      margin: 0 0 15px;
      color: #3f51b5;
    }
  }
  .response-rate {
    grid-column: 1 / -1;
    background: #f5f5f5;

    mat-card-content {
      display: flex;
      justify-content: space-around;
      font-size: 1.2em;
    }
  }
  .user-records {
    width: 100%;
    margin-top: 20px;
  }
  mat-chip {
    margin: 5px;
  }
}

end


http://www.kler.cn/a/572802.html

相关文章:

  • ubuntu24.04 经常更新内核,导致GPU不能用,如何锁定内核版本
  • 树状数组倍增
  • 轮训调接口
  • AI生成的web框架 包含前后端 k8s管理等
  • 火语言RPA--删除PDF页
  • 电子电气架构 --- 集成式与分布式的对比
  • 深度生成模型(四)——VAE 简单项目实战 VAE on CelebA
  • 06 HarmonyOS Next性能优化之LazyForEach 列表渲染基础与实现详解 (一)
  • Pytorch的一小步,昇腾芯片的一大步
  • 演示汉字笔顺的工具
  • 构建一个Django的应用程序
  • MATLAB仿真:涡旋光束光强和相位分布同时展示
  • 图漾PercipioIPTool软件使用
  • setlocale()的参数,“zh_CN.UTF-8“, “chs“, “chinese-simplified“的差异。
  • 人工智能神经网络基本原理
  • STM32---FreeRTOS中断管理试验
  • KIKKKKKKK::::::::::::::
  • MR 1. 孟德尔随机化在生物医学研究中的应用概述
  • 探秘鸿蒙 HarmonyOS NEXT:权限申请策略指南
  • Linux网络 NAT、代理服务、内网穿透