class Image(db.Document): """Reference to an image on Instagram.""" id = db.StringField(required=True, primary_key=True) user = db.ReferenceField(InstagramUser) url = db.StringField(required=True, unique=True) description = db.StringField(required=True) location = db.PointField()
class Transaction(db.Document): userId = db.ObjectIdField(required=True) fromAddress = db.StringField(required=True, max_length=200) fromCurrency = db.StringField(required=True, max_length=20) toAddress = db.StringField(required=True, max_length=200) toCurrency = db.StringField(required=True, max_length=20) amount = db.DecimalField(required=True, precision=10) senderDeviceId = db.IntField(required=False) senderIp = db.StringField(required=False, max_length=20) country = db.StringField(required=False, max_length=20) transactedAt = db.DateTimeField( required=False) # StringField(required=False, max_length=15) score = db.DecimalField(required=True, default=0) txHash = db.StringField(required=False, max_length=200) createdAt = db.DateTimeField(default=datetime.utcnow) updatedAt = db.DateTimeField() updatedBy = db.StringField(max_length=100) meta = { 'collection': 'transactions', 'indexes': [ 'userId', 'fromAddress', 'fromCurrency', '-transactedAt', '-createdAt', 'score' ] }
class UserApi(db.Document): userId = db.ObjectIdField(required=True) apiName = db.StringField(max_length=100) apiKey = db.StringField(required=True, unique=True, max_length=100) apiSecret = db.StringField(required=True, max_length=300) isActive = db.BooleanField(required=True, default=True) createdAt = db.DateTimeField(required=True, default=datetime.utcnow) createdBy = db.StringField(required=True, max_length=100) updatedAt = db.DateTimeField() updatedBy = db.StringField(max_length=100) meta = { 'collection': 'userApi', 'indexes': ['userId', 'apiKey', '-createdAt'] }
class User(db.Document): """User model """ username = db.StringField() password = db.StringField() def to_json2(self): """Returns a json representantion of the user. :returns: a json object. """ return { 'id': str(self.id), 'username': self.username }
class DeviceType(db.Document): deviceId = db.IntField(required=True) deviceType = db.StringField(required=True, max_length=50) meta = {'collection': 'deviceType'} @queryset_manager def objects(doc_cls, queryset): # noqa return queryset.order_by('deviceId')
class UserAccessToken(db.Document): userId = db.ObjectIdField(required=True) accessToken = db.StringField(required=True, max_length=1000) expireAt = db.DateTimeField(required=True) CreatedAt = db.DateTimeField(default=datetime.utcnow) meta = { 'collection': 'userAccessToken', 'indexes': ['userId', '-accessToken', 'expireAt'] }
class Resolution(db.Document): # 目标问题id targetProblemId = db.IntField() # 问题类型 type = db.StringField() # 问题答案 resolution = db.ListField() # 通过problemid拿到这个问题下的所有解答记录 @staticmethod def getResolutionByPid(pid): resolution = Resolution.objects.filter(targetProblemId=pid) return resolution
class User(db.Document): username = db.StringField(required=True, unique=True, max_length=100) password = db.StringField(required=True, max_length=100) company = db.StringField(max_length=100) email = db.StringField(required=True, max_length=100) contactNumber = db.StringField(max_length=100) address = db.StringField(max_length=200) billingType = db.ObjectIdField() emailVerified = db.BooleanField(required=True, default=False) roleType = db.StringField(required=True, default="User", regex=r'^(Admin|User)$') isActive = db.BooleanField(required=True, default=True) lastSignin = db.DateTimeField() createdAt = db.DateTimeField(required=True, default=datetime.utcnow) createdBy = db.StringField(required=True) updatedAt = db.DateTimeField() updatedBy = db.StringField(max_length=100) meta = { 'collection': 'user', 'indexes': ['username', 'email', '-createdAt'] }
class InstagramUser(db.Document): """Metadata for Instagram user with tracked images.""" id = db.StringField(required=True, primary_key=True) username = db.StringField(required=True) bio = db.StringField(required=True) profile_picture = db.StringField(required=True, unique=True)
class BillingType(db.Document): billingType = db.StringField(required=True, regex=r'^(Monthly|Metered)$', unique=True) meta = {'collection': 'billingType'}
class User(db.Document): """A user of the gramHammer web application.""" username = db.StringField(required=True, unique=True) instagram_username = db.ReferenceField(InstagramUser) email = db.EmailField(required=True, unique=True) password = db.StringField(required=True)
class Problem(db.Document): # 标题 title = db.StringField() # 问题类型 type = db.StringField() # 问题选项 options = db.ListField() # 是否必填 isRequire = db.BooleanField(default=False) # 问题标记 是一个时间戳 便于问卷排序 problemId = db.IntField() # 对应问卷 targetQuestionnaireId = db.IntField() # 拥有者id ownerId = db.StringField() # 添加一个问题 def appendOneProblem(self, ownerId, form): # 检查问卷是不是自己的 q = Questionnaire.objects.filter( ownerId=ownerId, questionnaireId=form.targetQuestionnaireId.data).first() if not q: raise NoQuestionnaire self.targetQuestionnaireId = form.targetQuestionnaireId.data self.title = form.title.data self.type = form.type.data self.ownerId = ownerId self.problemId = getUniqueId() self.save() return self.problemId def getProblemJson(self): payLoad = { "title": self.title, "type": self.type, "options": self.options, "isRequire": self.isRequire, "problemId": self.problemId, "targetQuestionnaireId": self.targetQuestionnaireId, } return payLoad def getResolution(self): from app.models.resolution import Resolution optionRes = [] res = Resolution.getResolutionByPid(self.problemId) # 填空题 if self.type == "BLANK_FILL": for r in res: if len(r.resolution) is 0: continue optionRes.append(r.resolution[0]) # 单选题 下拉题 if self.type == "SINGLE_SELECT" or self.type == "DROP_DOWN": optionRes = self.options for r in res: if len(r.resolution) is 0: continue pos = int(r.resolution[0]) if 'resolution' not in optionRes[pos]: optionRes[pos]['resolution'] = 1 else: optionRes[pos]['resolution'] += 1 # 多选题 if self.type == "MULTIPLY_SELECT": optionRes = self.options for r in res: if len(r.resolution) is 0: continue for pos in r.resolution: pos = int(pos) if 'resolution' not in optionRes[pos]: optionRes[pos]['resolution'] = 1 else: optionRes[pos]['resolution'] += 1 # 评价题 if self.type == "SCORE": # 表示一到五颗星 开始设置为0 optionRes = [] for i in range(1, 6): optionRes.append({"title": i, "resolution": 0}) for r in res: if len(r.resolution) is 0: continue score = r.resolution[0] optionRes[score]["resolution"] += 1 return { # 返回的问题标题 "title": self.title, # 问题统计数组 "resolution": optionRes, "type": self.type, "problemId": self.problemId } @staticmethod def deleteOneProblem(ownerId, problemId): p = Problem.objects.filter(ownerId=ownerId, problemId=problemId).first() if not p: raise NoProblem p.delete() @staticmethod def deleteProblems(ownerId, questionnaireId): ps = Problem.objects.filter(ownerId=ownerId, targetQuestionnaireId=questionnaireId) ps.delete() # 编辑一个问题 @staticmethod def editOneProblem(ownerId, problemId, form): p = Problem.objects.filter(ownerId=ownerId, problemId=problemId).first() if not p: raise NoProblem p.title = form.title.data # 这里不加data p.options = form.jsonData['options'] p.isRequire = form.isRequire.data p.type = form.type.data p.save() @staticmethod def getProblems(qid): # 按照problemid 其实是时间戳 创建的顺序其实代表了题号的顺序 保证题号不乱 problems = [] ps = Problem.objects.filter( targetQuestionnaireId=qid).order_by('problemId') for p in ps: problems.append(p.getProblemJson()) return problems @staticmethod def createByTemplates(title, ptype, opt, pid, ownerId, tqid): Problem(title=title, type=ptype, options=opt, problemId=pid, ownerId=ownerId, targetQuestionnaireId=tqid).save() @staticmethod def getOneProblemByPid(pid, oid): p = Problem.objects.filter(problemId=pid, ownerId=oid).first() if not p: raise NoProblem return p.getProblemJson()
class Product(db.Document): name = db.StringField(max_length=50, required=True) description = db.StringField(max_length=50, required=True) callback_url = db.URLField(required=True)
class User(db.Document): # 用户名 userName = db.StringField() # 密码 passwordHash = db.StringField() # 邮箱 email = db.StringField(max_length=30) # 邮箱是否激活 生产环境下默认设置为已经激活 isActive = db.BooleanField(default=True) # 用户昵称(小程序端) miniProgramId = db.StringField() # 用户类型 type = db.StringField() def getUserId(self): return str(self.id) @property def password(self): return self.passwordHash @password.setter def password(self, purePassword): self.passwordHash = generate_password_hash(purePassword) # 注册一个小程序端用户 def registerByWechat(self, userName, openid): self.userName = userName self.miniProgramId = openid self.type = "MINI_PROGRAM_USER" self.save() # 注册一个web端用户 def userRegister(self, userName, password): self.userName = userName self.password = password self.type = "WEB_USER" self.save() def checkPassword(self, purePassword): return check_password_hash(self.passwordHash, purePassword) # web端登录 @staticmethod def userLogin(userName, password): user = User.objects.filter(userName=userName).first() if not user: raise WrongUserName if not user.checkPassword(password): raise WrongPassword return user # 小程序端登录(如果这个用户不存在会自动注册) @staticmethod def userLoginByWeChat(userName, code): # 首先获取openID 拿到用户唯一标识 oid = getUserOpenid(code) u = User.objects.filter(miniProgramId=oid).first() if not u: # 这个用户不存在 自动注册一个 User().registerByWechat(userName, oid) newU = User.objects.filter(miniProgramId=oid).first() return newU @staticmethod def getTemplateUserId(): name = current_app.config['TEMPALTES_MANAGER'] return str(User.objects.filter(userName=name).first().id)
class Sensor(db.Document): device_uuid = db.StringField() sensort_type_options = ["temperature", "humidity"] sensor_type = db.StringField(choices=sensort_type_options) sensor_value = db.FloatField(min_value=0.0, max_value=100.0) sensor_reading_time = db.DateTimeField()
class Questionnaire(db.Document): # 发布者的唯一标识 ownerId = db.StringField() # 问卷唯一标识 questionnaireId = db.IntField() '''全局开关''' # 问卷运行状态 condition = db.BooleanField(default=False) # 问卷是否加密 isSecret = db.BooleanField(default=False) # 微信限制 wechatControl = db.BooleanField(default=False) # ip限制 ipControl = db.BooleanField(default=False) # 设备限制 equipmentControl = db.BooleanField(default=False) # 截止时间限制 deadlineControl = db.BooleanField(default=False) '''全局设置''' # 问卷密码 secretKey = db.StringField(default=None) # 问卷截止时间 deadline = db.DateTimeField(default=datetime.utcnow) # 问卷最后一次更新时间 renewTime = db.DateTimeField(default=datetime.utcnow) '''答题次数''' # 问卷访问过的ip questionnaireIP = db.ListField(default=[]) '''基本信息''' title = db.StringField(default="请为这个问卷创建一个标题") subTitle = db.StringField(default="请为这个问卷创建一个副标题") def getQuestionnaireId(self): return self.questionnaireId # 问卷不在限制时间范围内 将其状态置为false 表示不可访问 def makeItDead(self): self.condition = False self.save() # 新建一个问卷 def createQuestionnaire(self, ownerId): t = getUniqueId() self.questionnaireId = t self.ownerId = ownerId self.save() return self.questionnaireId # 返回前端的问卷状态 type 0 表示不需要密码 type1 表示需要密码 def getConditionJson(self, isAdmin): payLoad = { "questionnaireId": self.questionnaireId, "condition": self.condition, "isSecret": self.isSecret, "wechatControl": self.wechatControl, "ipControl": self.ipControl, "equipmentControl": self.equipmentControl, "deadlineControl": self.deadlineControl, "deadline": self.deadline, "renewTime": self.renewTime, "title": self.title, "subTitle": self.subTitle, "secretKey": self.secretKey if isAdmin else None, } return payLoad @staticmethod def deleteQuestionnaire(ownerId, questionnaireId): q = Questionnaire.objects.filter( ownerId=ownerId, questionnaireId=questionnaireId).first() if not q: raise NoQuestionnaire q.delete() @staticmethod def editQuestionnaire(ownerId, questionnaireId, form): q = Questionnaire.objects.filter( ownerId=ownerId, questionnaireId=questionnaireId).first() if not q: raise NoQuestionnaire keys = form.jsonKeys for info in keys: # 防止传入null时值被重置 if form[info].data is not None: q[info] = form[info].data q.save() @staticmethod def getConditions(questionnaireId, isAdmin): q = Questionnaire.objects.filter( questionnaireId=questionnaireId).first() if not q: raise NoQuestionnaire if checkTimeIsDead(q): q.makeItDead() return q.getConditionJson(isAdmin=isAdmin) @staticmethod def checkSecretKey(questionnaireId, key): from app.models.problem import Problem q = Questionnaire.objects.filter( questionnaireId=questionnaireId).first() if not q: raise NoQuestionnaire if q.secretKey != key and q.isSecret: raise WrongProblemSecretKey return { "basicInfo": q.getConditionJson(isAdmin=False), "problems": Problem.getProblems(questionnaireId) } @staticmethod def getQuestionnaire(ownerId, questionnaireId, isAdmin): from app.models.problem import Problem q = Questionnaire.objects.filter( ownerId=ownerId, questionnaireId=questionnaireId).first() if not q: raise NoQuestionnaire return { "basicInfo": q.getConditionJson(isAdmin=isAdmin), "problems": Problem.getProblems(questionnaireId) } def getQuestionniareQRCode(self): code = QRcode(str(self.questionnaireId)) return code.showQRImg() def downloadQuestionnaireQRCode(self): code = QRcode(str(self.questionnaireId)) return code.downloadQRImg() @staticmethod def getAllQuestionnaire(ownerId): qs = Questionnaire.objects.filter(ownerId=ownerId) res = [] for q in qs: res.append(q.getConditionJson(isAdmin=False)) return res @staticmethod def getAnalysisData(qid): from app.models.problem import Problem from app.models.complete import Complete from app.utils.dataCalculate import DataCalculate # 拿到所有problems resolutions = [] q = Questionnaire.objects.filter(questionnaireId=qid).first() if not q: raise NoQuestionnaire problems = Problem.objects.filter(targetQuestionnaireId=qid) completes = Complete.getCompleteAmount(qid) for p in problems: res = p.getResolution() resolutions.append(res) return { "data": resolutions, "basicInfo": { "totalComplete": completes, "renewTime": q.renewTime, "title": q.title, }, "provinceInfo": DataCalculate.getProvinceData(qid) } @staticmethod def getTemplatesBasicInfo(page): from app.models.user import User if not page: raise ParameterException tuid = User.getTemplateUserId() beginIndex = (page - 1) * 10 ts = Questionnaire.objects.filter(ownerId=tuid)[beginIndex:beginIndex + 10] templateList = [] for t in ts: templateList.append({ "title": t.title, "renewTime": t.renewTime, "info": t.subTitle, "id": t.questionnaireId }) return templateList @staticmethod def getTemplatesAmount(): from app.models.user import User tuid = User.getTemplateUserId() return len(Questionnaire.objects.filter(ownerId=tuid)) @staticmethod def copyTemplates(qid, uid): from app.models.user import User from app.models.problem import Problem templateUserId = User.getTemplateUserId() # 获得目标模板 newqid = getUniqueId() q = Questionnaire.objects.filter(questionnaireId=qid, ownerId=templateUserId).first() if not q: raise NoQuestionnaire Questionnaire.createByTemplates(uid, newqid, q.title, q.subTitle) ps = Problem.objects.filter(targetQuestionnaireId=qid) if not ps: raise NoProblem for p in ps: Problem.createByTemplates(p.title, p.type, p.options, getUniqueId(), uid, newqid) @staticmethod def createByTemplates(uid, qid, title, subTitle): Questionnaire(ownerId=uid, questionnaireId=qid, title=title, subTitle=subTitle).save()