wxapp_user.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. # -*- coding: utf-8 -*-
  2. from odoo import models, fields, api
  3. from .. import defs
  4. from ..controllers.client import Client2
  5. import logging
  6. _logger = logging.getLogger(__name__)
  7. class WxappUser(models.Model):
  8. _name = 'wxapp.user'
  9. _description = u'小程序用户'
  10. _inherits = {'res.partner': 'partner_id'}
  11. user_id = fields.Many2one('res.users', string='用户') # 用于将微信用户与odoo用户关联起来
  12. name = fields.Char(related='partner_id.name', string='昵称', inherited=True)
  13. open_id = fields.Char('OpenId', required=True, index=True)
  14. union_id = fields.Char('UnionId')
  15. gender = fields.Integer('gender')
  16. language = fields.Char('语言')
  17. phone = fields.Char('手机号码')
  18. country = fields.Char('国家')
  19. province = fields.Char('省份')
  20. city = fields.Char('城市')
  21. avatar = fields.Html('头像', compute='_compute_avatar')
  22. avatar_url = fields.Char('头像链接')
  23. register_ip = fields.Char('注册IP')
  24. last_login = fields.Datetime('登陆时间')
  25. ip = fields.Char('登陆IP')
  26. status = fields.Selection(defs.WechatUserStatus.attrs.items(), string='状态', default=defs.WechatUserStatus.default)
  27. register_type = fields.Selection(defs.WechatUserRegisterType.attrs.items(), string='注册来源',
  28. default=defs.WechatUserRegisterType.app)
  29. partner_id = fields.Many2one('res.partner', required=True, ondelete='restrict', string='关联联系人', auto_join=True) #
  30. address_ids = fields.One2many('res.partner', compute='_compute_address_ids', string='收货地址')
  31. _sql_constraints = [(
  32. 'wxapp_user_union_id_unique',
  33. 'UNIQUE (union_id, create_uid)',
  34. 'wechat user union_id with create_uid is existed!'
  35. ),
  36. (
  37. 'wxapp_user_open_id_unique',
  38. 'UNIQUE (open_id, create_uid)',
  39. 'wechat user open_id with create_uid is existed!'
  40. ),
  41. ]
  42. # @api.multi
  43. @api.depends('avatar_url')
  44. def _compute_avatar(self):
  45. for each_record in self:
  46. if each_record.avatar_url:
  47. each_record.avatar = """
  48. <img src="{avatar_url}" style="max-width:100px;">
  49. """.format(avatar_url=each_record.avatar_url)
  50. else:
  51. each_record.avatar = False
  52. @api.depends('partner_id')
  53. def _compute_address_ids(self):
  54. for obj in self:
  55. obj.address_ids = obj.partner_id.child_ids.filtered(lambda r: r.type == 'delivery')
  56. def write(self, vals):
  57. if 'user_id' in vals:
  58. self._delete_access_token(self.open_id)
  59. return super(WxappUser, self).write(vals)
  60. def _delete_access_token(self, open_id):
  61. if not open_id:
  62. return
  63. access_token_list = self.env['wxapp.access_token'].search([('open_id', '=', open_id)])
  64. for t in access_token_list:
  65. t.unlink()
  66. return
  67. def get_token(self, sub_domain): # 用于测试
  68. if not sub_domain:
  69. msg = u'>>> 获取微信token失败===缺少参数'
  70. _logger.error(msg)
  71. return False, msg
  72. try:
  73. config = self.env['wxapp.config'].sudo()
  74. app_id = config.get_config('app_id', sub_domain)
  75. secret = config.get_config('secret', sub_domain)
  76. client = Client2(app_id, secret)
  77. json = client.grant_token()
  78. _token = json["access_token"]
  79. expires_in = json["expires_in"]
  80. # print u'====>获取微信token返回数据:\n', _token, expires_in
  81. except Exception as e:
  82. msg = u'>>> 获取微信token失败===' + str(e)
  83. _logger.error(msg)
  84. return False, msg
  85. return True, _token + '====' + str(expires_in)
  86. def send_wx_message(self, user_id, sub_domain, template_id, data=None, page=None):
  87. if not sub_domain or not template_id or not user_id:
  88. msg = u'>>> 发送微信信息失败===缺少参数'
  89. _logger.error(msg)
  90. return False, msg
  91. open_id = self._query_user_open_id(user_id)
  92. if not open_id:
  93. msg = u'>>> 发送微信信息失败===没有找到用户ID{}对应的微信用户'.format(user_id)
  94. _logger.error(msg)
  95. return False, msg
  96. config = self.env['wxapp.config'].sudo()
  97. app_id = config.get_config('app_id', sub_domain)
  98. secret = config.get_config('secret', sub_domain)
  99. client = Client2(app_id, secret)
  100. client.page = page
  101. client.template_id = template_id
  102. client.data = data
  103. try:
  104. result = client.send_text_message(open_id)
  105. # print u'====>发送微信消息返回数据:\n', result
  106. except Exception as e:
  107. err = str(e)
  108. if err.startswith('40001'): # 获取新token后重发一遍
  109. # 举例:'40001: invalid credential, access_token is invalid or not latest rid: 5fc7045b-00dac6d4-64e8c29c'
  110. return self._resend(client, open_id)
  111. msg = u'>>> 发送微信信息失败===' + err + '>>>数据===' + str(data)
  112. _logger.error(msg)
  113. return False, msg
  114. return True, u''
  115. def _resend(self, client, open_id):
  116. try:
  117. client.get_new_token()
  118. result = client.send_text_message(open_id)
  119. # print u'====>获取新token后,发送微信消息返回数据:\n', result
  120. except Exception as e:
  121. msg = u'>>> 获取新token后,发送微信信息失败===' + str(e) + '>>>数据===' + str(client.data)
  122. _logger.error(msg)
  123. return False, msg
  124. return True, ''
  125. def _query_user_open_id(self, user_id):
  126. user = self.sudo().search([('user_id', '=', user_id)])
  127. if not user:
  128. return None
  129. return user[0].open_id