Начинаю работу с небольшого мини-приложения, и каждый день вместо того чтобы читать документацию, первым делом проверяю информацию в группе "Бань-цзунлун" (групповой опрос), заполняю таблицу ex
(бедный студент второго курса, ежедневно получает 99+ сообщений от группы). Так родилась идея создания мини-приложения для регистрации информации студентами. Вначале я просто создал простую форму для отправки данных, но после завершения работы мне показалось, что чего-то не хватает, поэтому функционал продолжал расти, проект постоянно рефакторился, многие вещи были изучены и применены на ходу. За примерно десять дней было сделано все, что можно было сделать, хотя, скорее всего, это значит, что проект был доведен до состояния, когда больше нет новых идей. Проект включает полный цикл взаимодействия клиентской и серверной части, однако из-за различий в концепциях дизайна данных на ранних и поздних этапах реализации, некоторые моменты могут выглядеть неоптимальными. Надеюсь, вы будете относиться к этому с пониманием... (* ゜ェ゜ *)
Не буду много говорить, сейчас расскажу о концепции проекта и некоторых аспектах его реализации.
Главная страница выглядит следующим образом: она состоит из слайдера с новостями о коронавирусе (данные берутся с сайта Dingxiangyuan) и картой распределения студентов университета во время зимних каникул. После того как студенты отправят свои данные, количество людей на карте для каждого региона будет обновлено.
Данные карты хранятся в облачной базе данных, где каждому региону соответствует отдельная запись.
{
"_id": "Шанхай",
"name": "Шанхай", // название провинции
"value": 87.0 // количество студентов данного университета в этой провинции
}
```Данные карты получены от облачной функции `getArea` и переданы на фронтенд-страницу для инициализации карты. Для примера можно обратиться к [версии echarts для WeChat Mini Programs](https://github.com/ecomfe/echarts-for-weixin/tree/master/pages/map), а также просмотреть мой исходный код. Здесь стоит отметить несколько проблем, возникших при создании карты. В частности, для отображения карты Китая требуется импортировать JSON данные карты Китая (находящиеся в папке `mapData`). Однако, в примерах версии echarts для WeChat Mini Programs приведены только JSON данные карты провинции Хэнань. Поэтому потребуется скопировать JSON данные карты Китая с сайта [echarts](https://github.com/apache/incubator-echarts/tree/master/map/json) и вставить их в соответствующий раздел папки `mapData`, чтобы успешно отобразить карту Китая (для других стран аналогично). Начальный опыт был довольно болезненным. Поскольку данные карты загружаются асинхронно, инициализация карты происходит после получения данных.
```markdown
этот. ecComponent = этот. selectComponent('#mychart-dom-bar');
wx. cloud. callFunction({
name: 'getArea'
}). then((res)=>{
let result = res. result;
let option = initOption(result);
этот. ecComponent. init((canvas, width, height) => {
// Получение canvas, width, height после вызова обратной функции
// Здесь инициализируется график
const chart = echarts. init(canvas, null, {
width: width,
height: height
});
chart. setOption(option);
// Привязка экземпляра графика к этому, чтобы его можно было использовать в других методах (например, dispose)
это;
});
``````javascript
чарт = chart;
return chart;
});
}
Карусель в виде карточек происходит от colorui, которая представляет собой библиотеку CSS для WeChat Mini Programs. Для использования достаточно добавить соответствующие классы.***
Студенты заполняют свое имя, номер студенческого билета и телефон, выбирают свой факультет и группу (в связи с ограниченностью времени были реализованы только несколько факультетов), указывают город своего местоположения, а также выбирают наличие лихорадки перед отправкой данных.
Пользовательские данные хранятся в облачной базе данных, где каждой записи соответствует один пользователь.```
//Пример записи пользователя
{
"passCity": [
"北京市-北京市-东城区" //текущее местоположение
],
"openId": "oLuLy5MxC_dnd0eZhDVESsoMRln0", //уникальный идентификатор пользователя
"isHot": 1.0, //1 - нет лихорадки, 2 - есть лихорадка
"admin": true, //администратор
"classId": 1.0, //идентификатор группы
"isCommited": 1.0, //было ли отправлено
"name": "Ма Хуатэнг", //имя
"phone": "18074815679", //номер телефона
"studentId": "1233545" //номер студенческого билета
}
### Вход
Перед первым отправлением данных будет запрос на получение информации пользователя для её последующего хранения в базе данных. Уникальный идентификатор пользователя — это `openId` WeChat. Поскольку используется облачная разработка, то получение `openId` очень просто — достаточно получить контекст пользователя в облаке. Если пользователь уже существует в базе данных, то ему будут возвращены соответствующие данные пользователя, если же он ещё не зарегистрирован, то его данные будут инициализированы и добавлены в базу данных.
// вход const cloud = require('wx-server-sdk'); cloud.init({ // API вызовы всегда совпадают с текущей средой выполнения облачной функции env: cloud.DYNAMIC_CURRENT_ENV }); const db = cloud.database().collection('пользователи');
## Входная точка облачной функции
```javascript
exports.main = async (event, context) => {
const {OPENID} = cloud.getWXContext();
let result = await db.where({
openId: OPENID
}).get();
// Если пользователь не найден в базе данных, то инициализировать данные и сохранить их в базе данных
if (!result.data.length) {
Object.assign(event.user, event.userInfo);
event.user.isPut = false;
event.user.isHot = 0;
event.user.passCity = [];
await db.add({
data: event.user
});
}
return result;
};
```
```
### Поданные данные
После того как пользователь заполняет информацию, это приведёт к вызову двух облачных функций — одной для обновления данных пользователя и добавления его в соответствующий класс, а второй для обновления карты данных и увеличения количества студентов в его регионе.```
// updateArea
exports.main = async (event, context) => {
const {OPENID} = cloud.getWXContext();
// Если студент уже отправил данные, то уменьшаем количество студентов в прошлом регионе на единицу
if (event.isCommited) {
let oldCity = await db.collection('пользователи').where({
openId: event.userInfo.openId
}).get();
oldCity = oldCity.data[0].passCity[0].slice(0, 2);
// Из-за сложностей с названием таких регионов, как Guangxi или Neimenggu, используется приближенное соответствие
await db.collection('area').where({
name: db.RegExp({
regexp: oldCity,
options: 'i'
})
}).update({
data: {
value: _.dec(1)
}
});
}
// Из-за сложностей с названием таких регионов, как Guangxi или Neimenggu, используется приближенное соответствие
await db.collection('area').where({
name: db.RegExp({
regexp: event.citys[0],
options: 'i'
})
}).update({
data: {
value: _.inc(1)
}
});
return 'ok';
};
```
### Обновление пользователя
```javascript
exports.main = async (event, context) => {
const {OPENID} = cloud.getWXContext();
const {name, phone, citys, isHot, studentId, classId} = event;
// При первой отправке будет передана принадлежность к классу, информация о студенте будет сохранена в таблицу соответствующего класса
if (classId) {
await db.collection('class').where({
classId
}).update({
data: {
commitedStudents: _.push({
name,
phone,
citys,
isHot: isHot - 0
})
}
});
}
await db.collection('user').where({
openId: OPENID
}).update({
data: {
name,
studentId,
phone,
classId,
passCity: citys,
isHot: isHot - 0,
isCommited: 1,
isPut: true
}
});
return 'ok';
};
```
***
## Административная страница
```Административная страница позволяет просматривать данные обо всех студентах в университете, находящихся в провинции Хубэй, а также о тех, кто имеет признаки лихорадки. Также можно просмотреть состояние сдачи отчетности конкретного класса и список студентов этого класса. Для доступа к этой странице требуется проверка прав пользователя, то есть запись `admin: true` должна присутствовать в записи пользователя, связанной с его `openId`. Эта запись должна быть добавлена вручную разработчиком в базу данных.``````
Анимация:

```
// Валидация прав пользователя
const cloud = require('wx-server-sdk')
cloud.init({
// Все вызовы API должны соответствовать текущей среде выполнения облачной функции
env: cloud.DYNAMIC_CURRENT_ENV
})
const db = cloud.database()
// Входная точка облачной функции
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
const OPENID = wxContext.OPENID || event.OPENID
let user = await db.collection('user').where({
openId: OPENID
}).get()
user = user.data[0]
if (!user.admin) {
return 'ошибка'
}
return 'ок'
}
```
Данные о классах хранятся в облачной базе данных в отдельной таблице, где каждая запись представляет собой один класс.
```json
{
"classId": 9, // ID класса
"name": "16 экономика 1", // Название класса
"student_sum": 50, // Общее количество студентов в классе
"committedStudents": [] // Студенты, которые уже представили свои данные, каждый студент представлен объектом
}
```
# Как запустить этот проект
* git clone git@github.com:Akakiiiiii/students-system.git
* cd students-system
* cd cloudfunctions
* npm i
* Импортируйте этот mini-program в WeChat Developer Tool и заполните **собственный appId**
* Откройте проект и перейдите в Cloud Development -> Database, создайте три таблицы: area, user, class. Затем импортируйте json-файлы из папки проекта json. Таблица area должна быть заполнена json-файлами с названием, содержащим слово area, и так далее. (init означает только инициализацию таблицы без данных. Если вы хотите увидеть эффект, используйте json-файлы без слова init.)
* В конце концов, загрузите все облачные функции через WeChat Developer Tool, выбрав установку зависимостей в облаке, чтобы запустить этот проект.# Полный проект доступен по адресу
**GitHub**: https://github.com/Akakiiiiii/students-system
**Если вам помог этот проект, ваша звезда будет очень ценна ~(^_^)~**
**Если вы заметили место для улучшения, мы будем рады, если вы откроете Issue или отправите Pull Request. (^_^)**
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )