fix redux reducers, prevent repeatedly data fetching. CAUTION: please run database/v2018_07_27.sql to change DB structure.

pull/275/head
Bosn 7 years ago
parent 67cc4dbee9
commit b781393520

@ -0,0 +1,8 @@
ALTER TABLE Interfaces
MODIFY priority BIGINT(11) NOT NULL DEFAULT 1;
ALTER TABLE Properties
MODIFY priority BIGINT(11) NOT NULL DEFAULT 1;
ALTER TABLE Modules
MODIFY priority BIGINT(11) NOT NULL DEFAULT 1;

@ -1,8 +1,11 @@
import { Table, Column, Model, HasMany, AutoIncrement, PrimaryKey, AllowNull, DataType, Default, BelongsTo, ForeignKey, BeforeBulkDelete, BeforeBulkCreate, BeforeBulkUpdate, BeforeCreate, BeforeUpdate, BeforeDelete } from 'sequelize-typescript' import { Table, Column, Model, HasMany, AutoIncrement, PrimaryKey, AllowNull, DataType, Default, BelongsTo, ForeignKey, BeforeBulkDelete, BeforeBulkCreate, BeforeBulkUpdate, BeforeCreate, BeforeUpdate, BeforeDelete } from 'sequelize-typescript'
import { User, Module, Repository, Property } from '../'; import { User, Module, Repository, Property } from '../';
import RedisService, { CACHE_KEY } from '../../service/redis' import RedisService, { CACHE_KEY } from '../../service/redis'
import * as Sequelize from 'sequelize'
enum methods { GET= 'GET', POST= 'POST', PUT= 'PUT', DELETE= 'DELETE' } const Op = Sequelize.Op
enum methods { GET = 'GET', POST = 'POST', PUT = 'PUT', DELETE = 'DELETE' }
@Table({ paranoid: true, freezeTableName: false, timestamps: true }) @Table({ paranoid: true, freezeTableName: false, timestamps: true })
export default class Interface extends Model<Interface> { export default class Interface extends Model<Interface> {
@ -12,7 +15,7 @@ export default class Interface extends Model<Interface> {
@BeforeUpdate @BeforeUpdate
@BeforeDelete @BeforeDelete
static async deleteCache(instance: Interface) { static async deleteCache(instance: Interface) {
await RedisService.delCache(CACHE_KEY.REPOSITORY_GET, instance.repositoryId) await RedisService.delCache(CACHE_KEY.REPOSITORY_GET, instance.repositoryId)
} }
@BeforeBulkCreate @BeforeBulkCreate
@ -23,9 +26,15 @@ export default class Interface extends Model<Interface> {
if (!id) { if (!id) {
id = options.where && +options.where.id id = options.where && +options.where.id
} }
if (options.where && options.where[Op.and]) {
const arr = options.where[Op.and]
if (arr && arr[1] && arr[1].id) {
id = arr[1].id
}
}
if (id) { if (id) {
const itf = await Interface.findById(id) const itf = await Interface.findById(id)
await RedisService.delCache(CACHE_KEY.REPOSITORY_GET, itf.repositoryId) await RedisService.delCache(CACHE_KEY.REPOSITORY_GET, itf.repositoryId)
} }
} }
@ -48,7 +57,7 @@ export default class Interface extends Model<Interface> {
url: string url: string
@AllowNull(false) @AllowNull(false)
@Column({ type: DataType.ENUM(methods.GET, methods.POST, methods.PUT, methods.DELETE), comment: 'API method' }) @Column({ comment: 'API method' })
method: string method: string
@Column(DataType.TEXT) @Column(DataType.TEXT)

@ -1,6 +1,6 @@
// TODO 2.1 大数据测试,含有大量模块、接口、属性的仓库 // TODO 2.1 大数据测试,含有大量模块、接口、属性的仓库
import router from './router' import router from './router'
const _ = require('underscore') import * as _ from 'underscore'
import Pagination from './utils/pagination' import Pagination from './utils/pagination'
import { User, Organization, Repository, Module, Interface, Property, QueryInclude, Logger } from '../models' import { User, Organization, Repository, Module, Interface, Property, QueryInclude, Logger } from '../models'
import { Sequelize } from 'sequelize-typescript' import { Sequelize } from 'sequelize-typescript'
@ -96,6 +96,7 @@ router.get('/repository/list', async (ctx) => {
pagination: pagination, pagination: pagination,
} }
}) })
router.get('/repository/owned', async (ctx) => { router.get('/repository/owned', async (ctx) => {
let where = {} let where = {}
let { name } = ctx.query let { name } = ctx.query
@ -171,6 +172,7 @@ router.get('/repository/joined', async (ctx) => {
pagination: undefined, pagination: undefined,
} }
}) })
router.get('/repository/get', async (ctx) => { router.get('/repository/get', async (ctx) => {
const access = await AccessUtils.canUserAccess(ACCESS_TYPE.REPOSITORY, ctx.session.id, ctx.query.id) const access = await AccessUtils.canUserAccess(ACCESS_TYPE.REPOSITORY, ctx.session.id, ctx.query.id)
if (access === false) { if (access === false) {
@ -206,6 +208,7 @@ router.get('/repository/get', async (ctx) => {
data: repository, data: repository,
} }
}) })
router.post('/repository/create', async (ctx, next) => { router.post('/repository/create', async (ctx, next) => {
let creatorId = ctx.session.id let creatorId = ctx.session.id
let body = Object.assign({}, ctx.request.body, { creatorId, ownerId: creatorId }) let body = Object.assign({}, ctx.request.body, { creatorId, ownerId: creatorId })
@ -408,12 +411,15 @@ router.post('/module/create', async (ctx, next) => {
}) })
}) })
router.post('/module/update', async (ctx, next) => { router.post('/module/update', async (ctx, next) => {
let body = ctx.request.body const { id, name, description } = ctx.request.body
let result = await Module.update(body, { await Module.update({ name, description }, {
where: { id: body.id }, where: { id }
}) })
ctx.body = { ctx.body = {
data: result[0], data: {
name,
description,
},
} }
return next() return next()
}, async (ctx) => { }, async (ctx) => {
@ -527,7 +533,9 @@ router.post('/interface/create', async (ctx, next) => {
let created = await Interface.create(body) let created = await Interface.create(body)
// await initInterface(created) // await initInterface(created)
ctx.body = { ctx.body = {
data: await Interface.findById(created.id), data: {
itf: await Interface.findById(created.id),
}
} }
return next() return next()
}, async (ctx) => { }, async (ctx) => {
@ -543,11 +551,13 @@ router.post('/interface/create', async (ctx, next) => {
router.post('/interface/update', async (ctx, next) => { router.post('/interface/update', async (ctx, next) => {
let body = ctx.request.body let body = ctx.request.body
let result = await Interface.update(body, { await Interface.update(body, {
where: { id: body.id }, where: { id: body.id }
}) })
ctx.body = { ctx.body = {
data: result[0], data: {
itf: await Interface.findById(body.id),
}
} }
return next() return next()
}, async (ctx) => { }, async (ctx) => {
@ -631,50 +641,66 @@ router.get('/__test__', async (ctx) => {
router.post('/interface/lock', async (ctx, next) => { router.post('/interface/lock', async (ctx, next) => {
if (!ctx.session.id) { if (!ctx.session.id) {
ctx.body = { data: 0 } ctx.body = Consts.COMMON_ERROR_RES.NOT_LOGIN
return return
} }
let { id } = ctx.request.body let { id } = ctx.request.body
let itf = await Interface.findById(id) let itf = await Interface.findById(id, {
attributes: ['lockerId'],
include: [
QueryInclude.Locker,
]
})
if (itf.lockerId) { // DONE 2.3 BUG 接口可能被不同的人重复锁定。如果已经被锁定,则忽略。 if (itf.lockerId) { // DONE 2.3 BUG 接口可能被不同的人重复锁定。如果已经被锁定,则忽略。
ctx.body = { ctx.body = {
data: 0, data: itf.locker,
} }
return return
} }
const itf2 = await Interface.findById(id) await Interface.update({ lockerId: ctx.session.id }, { where: { id } })
itf2.lockerId = ctx.session.id itf = await Interface.findById(id, {
await itf2.save() attributes: ['lockerId'],
include: [
QueryInclude.Locker,
]
})
ctx.body = { ctx.body = {
data: itf2 data: itf.locker,
} }
return next() return next()
}) })
router.post('/interface/unlock', async (ctx, next) => { router.post('/interface/unlock', async (ctx) => {
if (!ctx.session.id) { if (!ctx.session.id) {
ctx.body = { data: 0 } ctx.body = Consts.COMMON_ERROR_RES.NOT_LOGIN
return return
} }
let { id } = ctx.request.body let { id } = ctx.request.body
let itf = await Interface.findById(id) let itf = await Interface.findById(id, { attributes: ['lockerId'] })
if (itf.lockerId !== ctx.session.id) { // DONE 2.3 BUG 接口可能被其他人解锁。如果不是同一个用户,则忽略。 if (itf.lockerId !== ctx.session.id) { // DONE 2.3 BUG 接口可能被其他人解锁。如果不是同一个用户,则忽略。
ctx.body = { data: 0 } ctx.body = {
isOk: false,
errMsg: '您不是锁定该接口的用户,无法对其解除锁定状态。请刷新页面。',
}
return return
} }
await Interface.update({
// tslint:disable-next-line:no-null-keyword
lockerId: null,
}, {
where: { id }
})
const itf2 = await Interface.findById(id)
// tslint:disable-next-line:no-null-keyword
itf2.lockerId = null
await itf2.save()
ctx.body = { ctx.body = {
data: itf2 data: {
isOk: true,
}
} }
return next()
}) })
router.post('/interface/sort', async (ctx) => { router.post('/interface/sort', async (ctx) => {
let { ids } = ctx.request.body let { ids } = ctx.request.body
let counter = 1 let counter = 1
@ -688,12 +714,12 @@ router.post('/interface/sort', async (ctx) => {
} }
}) })
//
router.get('/property/count', async (ctx) => { router.get('/property/count', async (ctx) => {
ctx.body = { ctx.body = {
data: 0 data: 0
} }
}) })
router.get('/property/list', async (ctx) => { router.get('/property/list', async (ctx) => {
let where: any = {} let where: any = {}
let { repositoryId, moduleId, interfaceId, name } = ctx.query let { repositoryId, moduleId, interfaceId, name } = ctx.query
@ -705,6 +731,7 @@ router.get('/property/list', async (ctx) => {
data: await Property.findAll({ where }), data: await Property.findAll({ where }),
} }
}) })
router.get('/property/get', async (ctx) => { router.get('/property/get', async (ctx) => {
let { id } = ctx.query let { id } = ctx.query
ctx.body = { ctx.body = {
@ -713,6 +740,7 @@ router.get('/property/get', async (ctx) => {
}), }),
} }
}) })
router.post('/property/create', async (ctx) => { router.post('/property/create', async (ctx) => {
let creatorId = ctx.session.id let creatorId = ctx.session.id
let body = Object.assign(ctx.request.body, { creatorId }) let body = Object.assign(ctx.request.body, { creatorId })
@ -723,6 +751,7 @@ router.post('/property/create', async (ctx) => {
}), }),
} }
}) })
router.post('/property/update', async (ctx) => { router.post('/property/update', async (ctx) => {
let properties = ctx.request.body // JSON.parse(ctx.request.body) let properties = ctx.request.body // JSON.parse(ctx.request.body)
properties = Array.isArray(properties) ? properties : [properties] properties = Array.isArray(properties) ? properties : [properties]
@ -738,12 +767,13 @@ router.post('/property/update', async (ctx) => {
data: result, data: result,
} }
}) })
router.post('/properties/update', async (ctx, next) => { router.post('/properties/update', async (ctx, next) => {
const itfId = +ctx.query.itf const itfId = +ctx.query.itf
let { properties, summary } = ctx.request.body // JSON.parse(ctx.request.body) let { properties, summary } = ctx.request.body // JSON.parse(ctx.request.body)
properties = Array.isArray(properties) ? properties : [properties] properties = Array.isArray(properties) ? properties : [properties]
const itf = await Interface.findById(itfId) let itf = await Interface.findById(itfId)
if (typeof summary.name !== 'undefined') { if (typeof summary.name !== 'undefined') {
itf.name = summary.name itf.name = summary.name
@ -808,8 +838,14 @@ router.post('/properties/update', async (ctx, next) => {
where: { id: item.id }, where: { id: item.id },
}) })
} }
itf = await Interface.findById(itfId, {
include: (QueryInclude.RepositoryHierarchy as any).include[0].include,
})
ctx.body = { ctx.body = {
data: result, data: {
result,
properties: itf.properties,
}
} }
return next() return next()
}, async (ctx) => { }, async (ctx) => {
@ -825,6 +861,7 @@ router.post('/properties/update', async (ctx, next) => {
interfaceId: itf.id, interfaceId: itf.id,
}) })
}) })
router.get('/property/remove', async (ctx) => { router.get('/property/remove', async (ctx) => {
let { id } = ctx.query let { id } = ctx.query
ctx.body = { ctx.body = {

@ -3,6 +3,7 @@ export enum COMMON_MSGS {
} }
export const COMMON_ERROR_RES = { export const COMMON_ERROR_RES = {
ERROR_PARAMS: { isOk: false, errMsg: 'Incorrect params.' }, ERROR_PARAMS: { isOk: false, errMsg: '参数错误' },
ACCESS_DENY: { isOk: false, errMsg: 'Access forbidden' }, ACCESS_DENY: { isOk: false, errMsg: '您没有访问权限' },
NOT_LOGIN: { isOk: false, errMsg: '您未登陆,或登陆状态过期。请登陆后重试' },
} }
Loading…
Cancel
Save