添加给合作伙伴的接口和文档
This commit is contained in:
parent
946c3b2065
commit
3e4f1297f2
254
doc/partner.md
254
doc/partner.md
@ -2,12 +2,55 @@
|
|||||||
|
|
||||||
## 修改记录
|
## 修改记录
|
||||||
|
|
||||||
|
### 20210620
|
||||||
|
第一版
|
||||||
|
|
||||||
## 说明
|
## 说明
|
||||||
|
|
||||||
1. 所有请求参数中带*号的不能为空
|
1. 所有接口均使用POST提交数据, Content-Type为application/json
|
||||||
2. 接口签名字段说明
|
|
||||||
|
例: curl
|
||||||
|
```shell
|
||||||
|
curl --location --request POST 'https://puzzle-admin.kingsome.cn/api/partner/login' \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data-raw '{
|
||||||
|
"name": "北京金蚕网络科技有限公司",
|
||||||
|
"sid": "123456789j",
|
||||||
|
"timestamp": 1624333003587,
|
||||||
|
"sign": "c4cfdad34de8fe8787cb8c74abe7a8692e11725ff582271b57ff1ebaa00b488a",
|
||||||
|
"logo": "https://resource.kingsome.cn/test60d07f3fb40504740fdccb6e.png"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
例: php
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
require_once 'HTTP/Request2.php';
|
||||||
|
$request = new HTTP_Request2();
|
||||||
|
$request->setUrl('http://127.0.0.1:2900/api/partner/login');
|
||||||
|
$request->setMethod(HTTP_Request2::METHOD_POST);
|
||||||
|
$request->setConfig(array(
|
||||||
|
'follow_redirects' => TRUE
|
||||||
|
));
|
||||||
|
$request->setHeader(array(
|
||||||
|
'Content-Type' => 'application/json'
|
||||||
|
));
|
||||||
|
$request->setBody('{\n "name": "北京金蚕网络科技有限公司",\n "sid": "123456789j",\n "timestamp": 1624333003587,\n "sign": "c4cfdad34de8fe8787cb8c74abe7a8692e11725ff582271b57ff1ebaa00b488a",\n "logo": "https://resource.kingsome.cn/test60d07f3fb40504740fdccb6e.png"\n}');
|
||||||
|
try {
|
||||||
|
$response = $request->send();
|
||||||
|
if ($response->getStatus() == 200) {
|
||||||
|
echo $response->getBody();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
|
||||||
|
$response->getReasonPhrase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(HTTP_Request2_Exception $e) {
|
||||||
|
echo 'Error: ' . $e->getMessage();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
2. 所有请求参数中带*号的不能为空
|
||||||
|
3. 接口签名字段说明
|
||||||
|
|
||||||
```
|
```
|
||||||
# 1. 将参与签名的参数按照key=value的格式,并按照参数名ASCII字典序升序排序, 例如:
|
# 1. 将参与签名的参数按照key=value的格式,并按照参数名ASCII字典序升序排序, 例如:
|
||||||
@ -16,7 +59,7 @@ var signStr = 'name=一品漫城&sid=65AB7856FE×tamp=1624332778169'
|
|||||||
var sign = HmacSHA256(signStr, secretKey)
|
var sign = HmacSHA256(signStr, secretKey)
|
||||||
|
|
||||||
```
|
```
|
||||||
3. 如无特殊说明, 所有接口返回json, 顶级结构如下, 接口Response的数据结构说明只包含data部分
|
4. 如无特殊说明, 所有接口返回json, 顶级结构如下, 接口Response的数据结构说明只包含data部分
|
||||||
|
|
||||||
``` JSON
|
``` JSON
|
||||||
{
|
{
|
||||||
@ -51,6 +94,7 @@ var sign = HmacSHA256(signStr, secretKey)
|
|||||||
|
|
||||||
### 1. 获取token
|
### 1. 获取token
|
||||||
|
|
||||||
|
> 这里获取的token用于调用页面时拼接url
|
||||||
1. Method: POST
|
1. Method: POST
|
||||||
2. URI: /api/partner/login
|
2. URI: /api/partner/login
|
||||||
|
|
||||||
@ -77,3 +121,205 @@ var sign = HmacSHA256(signStr, secretKey)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 2. 查询店铺信息
|
||||||
|
|
||||||
|
1. Method: POST
|
||||||
|
2. URI: /api/partner/shop/info
|
||||||
|
|
||||||
|
> POST参数
|
||||||
|
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
| -------- | -------------------------------------- |
|
||||||
|
| shop | *店铺id, 1号接口里上传的sid |
|
||||||
|
| timestamp | *10或13位均可 |
|
||||||
|
| sign | *签名 |
|
||||||
|
|
||||||
|
> 签名字段: shop, timestamp
|
||||||
|
|
||||||
|
|
||||||
|
3. Response: JSON
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
"_id": "店铺唯一id",
|
||||||
|
"sid": "店铺的短id",
|
||||||
|
"partnerId": "你们提供的店铺唯一id",
|
||||||
|
"name": "店铺名",
|
||||||
|
"showName": "店铺显示名",
|
||||||
|
"logo": "店铺logo的url地址",
|
||||||
|
"createdAt": "店铺创建时间",
|
||||||
|
"publish": true // 是否已发布
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 导入题库
|
||||||
|
|
||||||
|
1. Method: POST
|
||||||
|
2. URI: /api/partner/puzzle/import
|
||||||
|
|
||||||
|
> POST参数
|
||||||
|
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
| -------- | -------------------------------------- |
|
||||||
|
| shop| *店铺id |
|
||||||
|
| datas| *数据列表, 结构如下 |
|
||||||
|
| timestamp | *10或13位均可 |
|
||||||
|
| sign| *签名 |
|
||||||
|
|
||||||
|
> 签名字段: shop, timestamp
|
||||||
|
|
||||||
|
datas的数据示例
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"question": "烊行的“烊”字怎么念", // 题目
|
||||||
|
"a1": "羊", // 正确答案
|
||||||
|
"a2": "火", // 混淆答案1
|
||||||
|
"a3": "样", // 混淆答案2
|
||||||
|
"a4": "你猜我猜不猜8964", // 混淆答案3
|
||||||
|
"type": 1, // 题目类型, 1: 普通的题目, 3: 问卷
|
||||||
|
"groups": [ // 题目标签, 可当分类来用
|
||||||
|
"问卷"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
3. Response: JSON
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
"insert": 1, // 插入数量
|
||||||
|
"update": 0, // 更新同名题目数量
|
||||||
|
"skip": 0, // skip数量
|
||||||
|
"batch": 1624346272949 // 本次导入的批次
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 查询题库审核结果
|
||||||
|
|
||||||
|
1. Method: POST
|
||||||
|
2. URI: /api/partner/puzzle/status
|
||||||
|
|
||||||
|
> POST参数
|
||||||
|
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
| -------- | -------------------------------------- |
|
||||||
|
| shop | 店铺id |
|
||||||
|
| batch | *导入时返回的批次 |
|
||||||
|
| timestamp | *10或13位均可 |
|
||||||
|
| sign| *签名 |
|
||||||
|
|
||||||
|
> 签名字段: shop, batch, timestamp
|
||||||
|
|
||||||
|
|
||||||
|
3. Response: JSON
|
||||||
|
|
||||||
|
```js
|
||||||
|
[ // 题目审核状态数组
|
||||||
|
{
|
||||||
|
"id": "60d18ea07938dbda87d2e346", // 题目唯一id
|
||||||
|
"q": "烊行的“烊”字怎么念", // 题目
|
||||||
|
"status": 0 // 0: 未审核, 1: 审核通过, -1: 审核未通过
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 5. 挑战列表
|
||||||
|
|
||||||
|
1. Method: POST
|
||||||
|
2. URI: /api/partner/exams
|
||||||
|
|
||||||
|
> POST参数
|
||||||
|
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
| -------- | -------------------------------------- |
|
||||||
|
| shop | 店铺id |
|
||||||
|
| timestamp | *10或13位均可 |
|
||||||
|
| sign| *签名 |
|
||||||
|
| start| 跳过的记录条数 |
|
||||||
|
| limit|读取记录条数 |
|
||||||
|
| key| 查询的关键字 |
|
||||||
|
|
||||||
|
> 签名字段: shop, timestamp
|
||||||
|
|
||||||
|
|
||||||
|
3. Response: JSON
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
"total": 1, // 总数
|
||||||
|
"start": 0, // 当前跳过的记录条数
|
||||||
|
"limit": 10, // 读取记录条数
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"_id": "60b4d97545f1f1530f2404de", // 挑战记录id
|
||||||
|
"name": "test", // 挑战名称
|
||||||
|
"createdAt": "2021-05-31T12:41:25.864Z", // 记录创建时间
|
||||||
|
"active": true, // 是否启用
|
||||||
|
"beginTime": 0, // 开始时间
|
||||||
|
"endTime": 1924963201000, // 结束时间
|
||||||
|
"source": 3, // 题目来源,0: 系统题目, 1: 自定义, 2: 店铺自定义题库, 3: 混合题库
|
||||||
|
"qcount": 2, // 每次挑战的题目数量
|
||||||
|
"timeone": 50 // 每道题目回答的最长时间(秒)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. 挑战记录导出
|
||||||
|
|
||||||
|
1. Method: POST
|
||||||
|
2. URI: /api/partner/historys
|
||||||
|
|
||||||
|
> POST参数
|
||||||
|
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
| -------- | -------------------------------------- |
|
||||||
|
| shop | *店铺id |
|
||||||
|
| exam| 挑战活动id |
|
||||||
|
| timestamp | *10或13位均可 |
|
||||||
|
| sign| *签名 |
|
||||||
|
| start| 跳过的记录条数 |
|
||||||
|
| limit|读取记录条数 |
|
||||||
|
|
||||||
|
|
||||||
|
> 签名字段: shop, timestamp
|
||||||
|
|
||||||
|
|
||||||
|
3. Response: JSON
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
"total": 6,
|
||||||
|
"start": 0,
|
||||||
|
"limit": 10,
|
||||||
|
"records": [{ // 记录数组
|
||||||
|
"_id": "60b4d97545f1f1530f2404df", // 记录唯一id
|
||||||
|
"status": 1, // 记录状态, 0: 未开始, 1: 进行中, 9: 结束
|
||||||
|
"createdAt": "2021-05-31T12:45:21.395Z", // 答题开始时间
|
||||||
|
"type": 2, // 记录类型, 2: 挑战活动
|
||||||
|
"activityId": "60b4d97545f1f1530f2404de", // 挑战活动id
|
||||||
|
"qcount": 10, // 当前局一共多少题
|
||||||
|
"accountId": "1111", // 玩家帐号id
|
||||||
|
"questions": [{ // 当前局的所有题目
|
||||||
|
"title": "1126", // 题目标题
|
||||||
|
"answers": [ // 答案数组, 第一个是正确答案
|
||||||
|
"你好啊啊啊",
|
||||||
|
"b",
|
||||||
|
"246"
|
||||||
|
],
|
||||||
|
"answer": 0 // 玩家回答的答案, -1为未回答
|
||||||
|
}],
|
||||||
|
"nickname": "", // 玩家昵称
|
||||||
|
"score": 300.57172, // 得分
|
||||||
|
"count": 2 // 玩家已回答题目数量
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
```
|
@ -8,6 +8,12 @@ import { Admin } from '../../models/admin/Admin'
|
|||||||
import { Game } from '../../models/content/Game'
|
import { Game } from '../../models/content/Game'
|
||||||
import { downloadRemoteFile } from '../../services/File'
|
import { downloadRemoteFile } from '../../services/File'
|
||||||
import { uploadToCDN } from '../../services/TencentCDN'
|
import { uploadToCDN } from '../../services/TencentCDN'
|
||||||
|
import { ShopPuzzle } from '../../models/shop/ShopPuzzle'
|
||||||
|
import { AuditTask } from '../../models/AuditTask'
|
||||||
|
import { AuditSvr } from '../../services/AuditSvr'
|
||||||
|
import { ShopExam } from '../../models/shop/ShopExam'
|
||||||
|
import { PuzzleSession } from '../../models/match/PuzzleSession'
|
||||||
|
import { GameUser } from '../../models/user/GameUser'
|
||||||
|
|
||||||
const SECRET_KEY = '37284c327e10d8b73cf4325f33a3de4b34032e3e'
|
const SECRET_KEY = '37284c327e10d8b73cf4325f33a3de4b34032e3e'
|
||||||
const passwd = customAlphabet('2345678abcdefghjkmnpqrstwxy', 10)
|
const passwd = customAlphabet('2345678abcdefghjkmnpqrstwxy', 10)
|
||||||
@ -25,7 +31,7 @@ class PartnerController extends BaseController {
|
|||||||
async login(req: any, res: any) {
|
async login(req: any, res: any) {
|
||||||
let { name, sname, sid, logo, timestamp, sign } = req.params
|
let { name, sname, sid, logo, timestamp, sign } = req.params
|
||||||
if (!name || !sid || !timestamp || !sign) {
|
if (!name || !sid || !timestamp || !sign) {
|
||||||
throw new ZError(10, '缺少必要参数')
|
throw new ZError(10, 'params mismatch')
|
||||||
}
|
}
|
||||||
const signKeys = ['name', 'sid', 'timestamp']
|
const signKeys = ['name', 'sid', 'timestamp']
|
||||||
if (!checkSign({ secretKey: SECRET_KEY, data: req.params, sign, signKeys })) {
|
if (!checkSign({ secretKey: SECRET_KEY, data: req.params, sign, signKeys })) {
|
||||||
@ -67,4 +73,176 @@ class PartnerController extends BaseController {
|
|||||||
const token = await res.jwtSign({ id: account.id })
|
const token = await res.jwtSign({ id: account.id })
|
||||||
return { token }
|
return { token }
|
||||||
}
|
}
|
||||||
|
@router('post /api/partner/shop/list')
|
||||||
|
async shopList(req: any) {
|
||||||
|
const { shop, timestamp, sign } = req.params
|
||||||
|
if (!shop || !timestamp || !sign) {
|
||||||
|
throw new ZError(10, 'params mismatch')
|
||||||
|
}
|
||||||
|
const signKeys = ['shop', 'timestamp']
|
||||||
|
if (!checkSign({ secretKey: SECRET_KEY, data: req.params, sign, signKeys })) {
|
||||||
|
throw new ZError(21, 'sign error')
|
||||||
|
}
|
||||||
|
const record = await Shop.findByPartnerId(shop)
|
||||||
|
if (!record) {
|
||||||
|
throw new ZError(11, 'shop not found')
|
||||||
|
}
|
||||||
|
|
||||||
|
return record.toPartnerJson()
|
||||||
|
}
|
||||||
|
|
||||||
|
@router('post /api/partner/puzzle/import')
|
||||||
|
async importPuzzle(req: any) {
|
||||||
|
let { datas, shop, sign, timestamp } = req.params
|
||||||
|
if (!Array.isArray(datas)) {
|
||||||
|
throw new ZError(11, '数据结构不正确, datas必须为数组')
|
||||||
|
}
|
||||||
|
if (!shop || !sign || !timestamp) {
|
||||||
|
throw new ZError(10, 'params mismatch')
|
||||||
|
}
|
||||||
|
const signKeys = ['shop', 'timestamp']
|
||||||
|
if (!checkSign({ secretKey: SECRET_KEY, data: req.params, sign, signKeys })) {
|
||||||
|
throw new ZError(21, 'sign error')
|
||||||
|
}
|
||||||
|
const record = await Shop.findByPartnerId(shop)
|
||||||
|
if (!record) {
|
||||||
|
throw new ZError(11, 'shop not found')
|
||||||
|
}
|
||||||
|
for (let data of datas) {
|
||||||
|
data.shop = record.id
|
||||||
|
if (!data.groups && data.tags) {
|
||||||
|
data.groups = data.tags.split(',')
|
||||||
|
}
|
||||||
|
delete data.status
|
||||||
|
}
|
||||||
|
let result: any = {}
|
||||||
|
const batchTag = Date.now()
|
||||||
|
const initStatus = { status: 0, deleted: 0, is_hide: 0, quality: 1, batchTag }
|
||||||
|
try {
|
||||||
|
datas.map(data => Object.assign(data, initStatus))
|
||||||
|
let results = await ShopPuzzle.bulkWrite(
|
||||||
|
datas.map(data => ({
|
||||||
|
updateOne: {
|
||||||
|
filter: { shop: data.shop, question: data.question },
|
||||||
|
update: { $set: data },
|
||||||
|
upsert: true,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
{ ordered: false },
|
||||||
|
)
|
||||||
|
result.insert = results.upsertedCount + results.insertedCount
|
||||||
|
result.update = results.modifiedCount
|
||||||
|
result.skip = 0
|
||||||
|
let records = await ShopPuzzle.find({ batchTag })
|
||||||
|
let ids = records.map(data => data._id + '')
|
||||||
|
let id = await AuditTask.addOneTask('shop_puzzle', ids)
|
||||||
|
new AuditSvr().addTask(id)
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
result.insert = err.upsertedCount + err.insertedCount
|
||||||
|
result.update = err.modifiedCount
|
||||||
|
}
|
||||||
|
result.batch = batchTag
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
@router('post /api/partner/puzzle/status')
|
||||||
|
async importPuzzleStatus(req: any) {
|
||||||
|
let { batch, shop, sign, timestamp } = req.params
|
||||||
|
if (!shop || !batch || !sign || !timestamp) {
|
||||||
|
throw new ZError(10, 'params mismatch')
|
||||||
|
}
|
||||||
|
const signKeys = ['batch', 'shop', 'timestamp']
|
||||||
|
if (!checkSign({ secretKey: SECRET_KEY, data: req.params, sign, signKeys })) {
|
||||||
|
throw new ZError(21, 'sign error')
|
||||||
|
}
|
||||||
|
let records = await ShopPuzzle.find({ batchTag: batch })
|
||||||
|
return records.map(data => {
|
||||||
|
return {
|
||||||
|
id: data._id,
|
||||||
|
q: data.question,
|
||||||
|
status: data.status,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@router('post /api/partner/exams')
|
||||||
|
async shopExams(req: any) {
|
||||||
|
let { shop, sign, timestamp } = req.params
|
||||||
|
if (!shop || !sign || !timestamp) {
|
||||||
|
throw new ZError(10, 'params mismatch')
|
||||||
|
}
|
||||||
|
const signKeys = ['shop', 'timestamp']
|
||||||
|
if (!checkSign({ secretKey: SECRET_KEY, data: req.params, sign, signKeys })) {
|
||||||
|
throw new ZError(21, 'sign error')
|
||||||
|
}
|
||||||
|
const record = await Shop.findByPartnerId(shop)
|
||||||
|
if (!record) {
|
||||||
|
throw new ZError(11, 'shop not found')
|
||||||
|
}
|
||||||
|
let { start, limit } = req.params
|
||||||
|
limit = +limit || 10
|
||||||
|
start = +start || 0
|
||||||
|
req.params.shop = record.id
|
||||||
|
let { opt, sort } = ShopExam.parseQueryParam(req.params)
|
||||||
|
let records = await ShopExam.find(opt).sort(sort).skip(start).limit(limit)
|
||||||
|
let count = await ShopExam.countDocuments(opt)
|
||||||
|
let results = records.map(data => data.toPartnerJson())
|
||||||
|
return {
|
||||||
|
total: count,
|
||||||
|
start,
|
||||||
|
limit,
|
||||||
|
records: results,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@router('post /api/partner/historys')
|
||||||
|
async shopRecords(req: any) {
|
||||||
|
let { shop, sign, timestamp } = req.params
|
||||||
|
if (!shop || !sign || !timestamp) {
|
||||||
|
throw new ZError(10, 'params mismatch')
|
||||||
|
}
|
||||||
|
const signKeys = ['shop', 'timestamp']
|
||||||
|
if (!checkSign({ secretKey: SECRET_KEY, data: req.params, sign, signKeys })) {
|
||||||
|
throw new ZError(21, 'sign error')
|
||||||
|
}
|
||||||
|
const shopRecord = await Shop.findByPartnerId(shop)
|
||||||
|
if (!shopRecord) {
|
||||||
|
throw new ZError(11, 'shop not found')
|
||||||
|
}
|
||||||
|
let { start, limit } = req.params
|
||||||
|
limit = +limit || 10
|
||||||
|
start = +start || 0
|
||||||
|
req.params.shop = shopRecord.id
|
||||||
|
let { opt, sort } = PuzzleSession.parseQueryParam(req.params)
|
||||||
|
let records = await PuzzleSession.find(opt).sort(sort).skip(start).limit(limit)
|
||||||
|
let count = await PuzzleSession.countDocuments(opt)
|
||||||
|
let results: any[] = []
|
||||||
|
let userMap = new Map<string, string>()
|
||||||
|
for (let record of records) {
|
||||||
|
let obj: any = record.toPartnerJson()
|
||||||
|
const accountId = obj.accountId
|
||||||
|
const stat = record.members.get(accountId)
|
||||||
|
let nickname = ''
|
||||||
|
if (userMap.has(accountId)) {
|
||||||
|
nickname = userMap.get(accountId)
|
||||||
|
} else {
|
||||||
|
const user = await GameUser.getByAccountID(accountId)
|
||||||
|
if (user) {
|
||||||
|
nickname = user.nickname
|
||||||
|
userMap.set(accountId, nickname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
obj.nickname = nickname
|
||||||
|
obj.score = stat.score
|
||||||
|
obj.count = stat.answer.size
|
||||||
|
results.push(obj)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
total: count,
|
||||||
|
start,
|
||||||
|
limit,
|
||||||
|
records: results,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,6 +212,49 @@ export class PuzzleSessionClass extends BaseModule {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return this.room + this._id
|
return this.room + this._id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static parseQueryParam(params) {
|
||||||
|
let { exam, timeBegin, timeEnd, shop } = params
|
||||||
|
let opt: any = { type: 2 }
|
||||||
|
if (shop) {
|
||||||
|
opt.shop = shop
|
||||||
|
}
|
||||||
|
if (exam) {
|
||||||
|
opt.activityId = exam
|
||||||
|
}
|
||||||
|
if (timeBegin && !timeEnd) {
|
||||||
|
opt.createdAt = { $gte: new Date(timeBegin) }
|
||||||
|
} else if (timeBegin && timeEnd) {
|
||||||
|
opt['$and'] = [{ createdAt: { $gte: new Date(timeBegin) } }, { createdAt: { $lte: new Date(timeEnd) } }]
|
||||||
|
} else if (!timeBegin && timeEnd) {
|
||||||
|
opt.createdAt = { $lte: new Date(timeEnd) }
|
||||||
|
}
|
||||||
|
let sort = { _id: 1 }
|
||||||
|
return { opt, sort }
|
||||||
|
}
|
||||||
|
|
||||||
|
public toPartnerJson() {
|
||||||
|
const exportKeys = ['_id', 'status', 'createdAt', 'type', 'activityId']
|
||||||
|
let result: any = {}
|
||||||
|
for (let key of exportKeys) {
|
||||||
|
result[key] = this[key]
|
||||||
|
}
|
||||||
|
result.qcount = this.questions.size
|
||||||
|
let questions: any = []
|
||||||
|
const accountId = this.members.keys().next().value
|
||||||
|
const udata = this.members.get(accountId)
|
||||||
|
result.accountId = accountId
|
||||||
|
for (let [key, data] of this.questions) {
|
||||||
|
let obj = {
|
||||||
|
title: data.title,
|
||||||
|
answers: data.answers,
|
||||||
|
answer: udata.answer.has(key) ? udata.answer.get(key) : -1,
|
||||||
|
}
|
||||||
|
questions.push(obj)
|
||||||
|
}
|
||||||
|
result.questions = questions
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PuzzleSession = getModelForClass(PuzzleSessionClass, { existingConnection: PuzzleSessionClass.db })
|
export const PuzzleSession = getModelForClass(PuzzleSessionClass, { existingConnection: PuzzleSessionClass.db })
|
||||||
|
@ -6,6 +6,7 @@ import { customAlphabet } from 'nanoid'
|
|||||||
import { isObjectId } from '../../utils/string.util'
|
import { isObjectId } from '../../utils/string.util'
|
||||||
import { ZError } from '../../common/ZError'
|
import { ZError } from '../../common/ZError'
|
||||||
import { INIT_KEY_NUM, MongoTool } from '../../services/MongoTool'
|
import { INIT_KEY_NUM, MongoTool } from '../../services/MongoTool'
|
||||||
|
import { Base, TimeStamps } from '@typegoose/typegoose/lib/defaultClasses'
|
||||||
|
|
||||||
const nanoid = customAlphabet('2345678abcdefghjkmnpqrstwxy', 10)
|
const nanoid = customAlphabet('2345678abcdefghjkmnpqrstwxy', 10)
|
||||||
|
|
||||||
@ -17,6 +18,9 @@ class GameInfo {
|
|||||||
public versionid: string
|
public versionid: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
export interface ShopClass extends Base, TimeStamps {}
|
||||||
|
|
||||||
@dbconn()
|
@dbconn()
|
||||||
@index({ location: '2dsphere' })
|
@index({ location: '2dsphere' })
|
||||||
@index({ sid: 1 }, { unique: true })
|
@index({ sid: 1 }, { unique: true })
|
||||||
@ -41,7 +45,7 @@ class GameInfo {
|
|||||||
this.numid = sid
|
this.numid = sid
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
class ShopClass extends BaseModule {
|
export class ShopClass extends BaseModule {
|
||||||
@prop()
|
@prop()
|
||||||
public sid: string
|
public sid: string
|
||||||
|
|
||||||
@ -215,6 +219,10 @@ class ShopClass extends BaseModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static findByPartnerId(pid: string) {
|
||||||
|
return Shop.findOne({ partnerId: pid })
|
||||||
|
}
|
||||||
|
|
||||||
public static async sid2ID(id: string) {
|
public static async sid2ID(id: string) {
|
||||||
if (isObjectId(id)) {
|
if (isObjectId(id)) {
|
||||||
return id
|
return id
|
||||||
@ -234,6 +242,15 @@ class ShopClass extends BaseModule {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public toPartnerJson() {
|
||||||
|
const exportKeys = ['_id', 'sid', 'partnerId', 'name', 'showName', 'logo', 'createdAt', 'publish']
|
||||||
|
let result: any = {}
|
||||||
|
for (let key of exportKeys) {
|
||||||
|
result[key] = this[key]
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isShopSid(id: string) {
|
export function isShopSid(id: string) {
|
||||||
|
@ -238,6 +238,27 @@ export class ShopExamClass extends BaseModule {
|
|||||||
}
|
}
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public toPartnerJson() {
|
||||||
|
const exportKeys = [
|
||||||
|
'_id',
|
||||||
|
'name',
|
||||||
|
'desc',
|
||||||
|
'logo',
|
||||||
|
'createdAt',
|
||||||
|
'active',
|
||||||
|
'beginTime',
|
||||||
|
'endTime',
|
||||||
|
'source',
|
||||||
|
'qcount',
|
||||||
|
'timeone',
|
||||||
|
]
|
||||||
|
let result: any = {}
|
||||||
|
for (let key of exportKeys) {
|
||||||
|
result[key] = this[key]
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ShopExam = getModelForClass(ShopExamClass, { existingConnection: ShopExamClass.db })
|
export const ShopExam = getModelForClass(ShopExamClass, { existingConnection: ShopExamClass.db })
|
||||||
|
Loading…
x
Reference in New Issue
Block a user