123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- # -*- coding: utf-8 -*-
- from odoo import models, fields, api
- from .. import defs
- from ..controllers.client import Client2
- import logging
- _logger = logging.getLogger(__name__)
- class WxappUser(models.Model):
- _name = 'wxapp.user'
- _description = u'小程序用户'
- _inherits = {'res.partner': 'partner_id'}
- user_id = fields.Many2one('res.users', string='用户') # 用于将微信用户与odoo用户关联起来
- name = fields.Char(related='partner_id.name', string='昵称', inherited=True)
- open_id = fields.Char('OpenId', required=True, index=True)
- union_id = fields.Char('UnionId')
- gender = fields.Integer('gender')
- language = fields.Char('语言')
- phone = fields.Char('手机号码')
- country = fields.Char('国家')
- province = fields.Char('省份')
- city = fields.Char('城市')
- avatar = fields.Html('头像', compute='_compute_avatar')
- avatar_url = fields.Char('头像链接')
- register_ip = fields.Char('注册IP')
- last_login = fields.Datetime('登陆时间')
- ip = fields.Char('登陆IP')
- status = fields.Selection(defs.WechatUserStatus.attrs.items(), string='状态', default=defs.WechatUserStatus.default)
- register_type = fields.Selection(defs.WechatUserRegisterType.attrs.items(), string='注册来源',
- default=defs.WechatUserRegisterType.app)
- partner_id = fields.Many2one('res.partner', required=True, ondelete='restrict', string='关联联系人', auto_join=True) #
- address_ids = fields.One2many('res.partner', compute='_compute_address_ids', string='收货地址')
- _sql_constraints = [(
- 'wxapp_user_union_id_unique',
- 'UNIQUE (union_id, create_uid)',
- 'wechat user union_id with create_uid is existed!'
- ),
- (
- 'wxapp_user_open_id_unique',
- 'UNIQUE (open_id, create_uid)',
- 'wechat user open_id with create_uid is existed!'
- ),
- ]
- # @api.multi
- @api.depends('avatar_url')
- def _compute_avatar(self):
- for each_record in self:
- if each_record.avatar_url:
- each_record.avatar = """
- <img src="{avatar_url}" style="max-width:100px;">
- """.format(avatar_url=each_record.avatar_url)
- else:
- each_record.avatar = False
- @api.depends('partner_id')
- def _compute_address_ids(self):
- for obj in self:
- obj.address_ids = obj.partner_id.child_ids.filtered(lambda r: r.type == 'delivery')
- def write(self, vals):
- if 'user_id' in vals:
- self._delete_access_token(self.open_id)
- return super(WxappUser, self).write(vals)
- def _delete_access_token(self, open_id):
- if not open_id:
- return
- access_token_list = self.env['wxapp.access_token'].search([('open_id', '=', open_id)])
- for t in access_token_list:
- t.unlink()
- return
- def get_token(self, sub_domain): # 用于测试
- if not sub_domain:
- msg = u'>>> 获取微信token失败===缺少参数'
- _logger.error(msg)
- return False, msg
- try:
- config = self.env['wxapp.config'].sudo()
- app_id = config.get_config('app_id', sub_domain)
- secret = config.get_config('secret', sub_domain)
- client = Client2(app_id, secret)
- json = client.grant_token()
- _token = json["access_token"]
- expires_in = json["expires_in"]
- # print u'====>获取微信token返回数据:\n', _token, expires_in
- except Exception as e:
- msg = u'>>> 获取微信token失败===' + str(e)
- _logger.error(msg)
- return False, msg
- return True, _token + '====' + str(expires_in)
- def send_wx_message(self, user_id, sub_domain, template_id, data=None, page=None):
- if not sub_domain or not template_id or not user_id:
- msg = u'>>> 发送微信信息失败===缺少参数'
- _logger.error(msg)
- return False, msg
- open_id = self._query_user_open_id(user_id)
- if not open_id:
- msg = u'>>> 发送微信信息失败===没有找到用户ID{}对应的微信用户'.format(user_id)
- _logger.error(msg)
- return False, msg
- config = self.env['wxapp.config'].sudo()
- app_id = config.get_config('app_id', sub_domain)
- secret = config.get_config('secret', sub_domain)
- client = Client2(app_id, secret)
- client.page = page
- client.template_id = template_id
- client.data = data
- try:
- result = client.send_text_message(open_id)
- # print u'====>发送微信消息返回数据:\n', result
- except Exception as e:
- err = str(e)
- if err.startswith('40001'): # 获取新token后重发一遍
- # 举例:'40001: invalid credential, access_token is invalid or not latest rid: 5fc7045b-00dac6d4-64e8c29c'
- return self._resend(client, open_id)
- msg = u'>>> 发送微信信息失败===' + err + '>>>数据===' + str(data)
- _logger.error(msg)
- return False, msg
- return True, u''
- def _resend(self, client, open_id):
- try:
- client.get_new_token()
- result = client.send_text_message(open_id)
- # print u'====>获取新token后,发送微信消息返回数据:\n', result
- except Exception as e:
- msg = u'>>> 获取新token后,发送微信信息失败===' + str(e) + '>>>数据===' + str(client.data)
- _logger.error(msg)
- return False, msg
- return True, ''
- def _query_user_open_id(self, user_id):
- user = self.sudo().search([('user_id', '=', user_id)])
- if not user:
- return None
- return user[0].open_id
|