from odoo import api, models, exceptions, fields import logging from odoo.http import request _logger = logging.getLogger(__name__) class WechatEnterpriseApp(models.Model): _name = 'we.app' _description = 'Wechat Enterprise App Manage' agentid = fields.Integer(string=u'应用ID', required=True) code = fields.Char(string=u'自定义代码') name = fields.Char(u'企业号应用名称') description = fields.Text(u'企业号应用详情') redirect_domain = fields.Char(u'企业应用可信域名') isreportuser = fields.Selection([('0', u'不接受'), ('1', u'接收')], u'变更通知', required=True, default='0') isreportenter = fields.Selection([('0', u'不接受'), ('1', u'接收')], u'进入应用事件上报', required=True, default='0') enterprise_id = fields.Many2one('we.config', string=u'企业微信') secret = fields.Char(string=u'Secret', size=100) home_url = fields.Char(u'主页型应用url') square_logo_url = fields.Char(u'方形头像url') round_logo_url = fields.Char(u'圆形头像url') type = fields.Selection([('1', u'消息型'), ('2', u'主页型')], u'应用类型', required=True, default='1') allow_userinfos = fields.Char(u'企业应用可见范围(人员)') allow_partys = fields.Char(u'企业应用可见范围(部门)') allow_tags = fields.Char(u'企业应用可见范围(标签)') report_location_flag = fields.Selection([('0', u'不上报'), ('1', u'进入会话上报'), ('2', u'持续上报')], u'位置上报', required=True, default='1') logo_mediaid = fields.Char(u'企业应用头像的mediaid') close = fields.Selection([('0', u'否'), ('1', u'是')], u'是否禁用', required=True, default='0') app_menu_ids = fields.One2many('we.app.menu', 'agentid', string=u'自定义菜单') Token = fields.Char(u'Token') EncodingAESKey = fields.Char(u'EncodingAESKey') def pull_app_from_we(self, wechat): """ 从微信获取app列表 :return: """ try: app_lists = wechat.agent.list() if app_lists: for app_list in app_lists: if 'agentid' in app_list: app_detail = wechat.agent.get(app_list['agentid']) if app_detail: data = { 'agentid': str(app_detail['agentid']) } my_app = request.env["we.app"].search( [("agentid", "=", str(app_detail['agentid']))]) if my_app and len(my_app) > 0: continue data['name'] = app_detail['name'] data['square_logo_url'] = app_detail['square_logo_url'] data['description'] = app_detail['description'] data['close'] = str(app_detail['close']) data['redirect_domain'] = app_detail['redirect_domain'] data['report_location_flag'] = str(app_detail['report_location_flag']) data['isreportenter'] = str(app_detail['isreportenter']) data['enterprise_id'] = self.id request.env["we.app"].create(data) except Exception as e: raise Warning((u'获取应用列表失败,原因:%s', str(e))) def push_app_to_we(self): """ 同步app到微信 :return: """ wechat = self.env['we.config'].sudo().get_wechat() if wechat: try: for account in self: app_json = { 'name': account.name } if account.description: app_json['description'] = account.description if account.redirect_domain: app_json['redirect_domain'] = account.redirect_domain app_json['agentid'] = int(account.agentid) app_json['report_location_flag'] = int(account.report_location_flag) if account.type == "1": # 消息型应用 if account.name and account.agentid \ and account.isreportuser and account.isreportenter and account.report_location_flag: app_json['isreportuser'] = int(account.isreportuser) app_json['isreportenter'] = int(account.isreportenter) wechat.agent.set(agent_id=app_json['agentid'], name=app_json['name'], description=app_json['description'], redirect_domain=app_json['redirect_domain'], is_report_user=app_json['isreportuser'], is_report_enter=app_json['isreportenter'], report_location_flag=app_json['report_location_flag']) elif account.type == "2": # 主页型应用 if account.name and account.agentid \ and account.report_location_flag and account.home_url: app_json['home_url'] = account.home_url wechat.agent.set(agent_id=app_json['agentid'], name=app_json['name'], description=app_json['description'], redirect_domain=app_json['redirect_domain'], is_report_user=app_json['isreportuser'], is_report_enter=app_json['isreportenter'], report_location_flag=app_json['report_location_flag']) except Exception as e: _logger.warning(u'更新app失败,原因:%s', str(e)) raise Warning(u'更新app失败,原因:%s', str(e)) else: raise exceptions.Warning(u"初始化企业号失败") def update_app_menu(self): """ 同步菜单至app :return: """ wechat = self.env['we.config'].sudo().get_wechat(agentID=self.agentid) menus = self.env['we.app.menu'].sudo().search([("agentid", "=", self.name)]) wechat.menu.delete(agent_id=self.agentid) menu_json = {'button': []} button = [] if wechat and menus: for menu in menus: menu_data = { 'name': menu['name'] } if not menu['partner_menu_id']: sub_menus = request.env['we.app.menu'].sudo().search( [("agentid", "=", self.name), ("partner_menu_id", "=", menu['name'])]) if sub_menus and (len(sub_menus) > 0) and (len(sub_menus) < 6): sub_menu_list = [] for sub_menu in sub_menus: sub_menu_data = { 'name': sub_menu['name'] } if menu['type'] == 'xml' or menu['type'] == 'sub_button': sub_menu_data['type'] = sub_menu['type'] sub_menu_data['url'] = sub_menu['url'] else: sub_menu_data['type'] = sub_menu['type'] sub_menu_data['key'] = sub_menu['key'] sub_menu_list.append(sub_menu_data) menu_data['sub_button'] = sub_menu_list else: if menu['type'] == 'xml' or menu['type'] == 'sub_button': menu_data['type'] = menu['type'] menu_data['url'] = menu['url'] else: menu_data['type'] = menu['type'] menu_data['key'] = menu['key'] button.append(menu_data) menu_json['button'] = button wechat.menu.update(agent_id=self.agentid, menu_data=menu_json) else: raise exceptions.Warning(u"初始化企业号失败或该应用无菜单") class WechatEnterpriseAppMenu(models.Model): _name = 'we.app.menu' _description = 'Wechat Enterprise App Menu Manage' agentid = fields.Many2one('we.app', u'企业应用', required=True) partner_menu_id = fields.Many2one('we.app.menu', u'上级菜单') type = fields.Selection( [('sub_button', u'跳转至子菜单'), ('click', u'点击推事件'), ('xml', u'跳转URL'), ('scancode_push', u'扫码推事件'), ('scancode_waitmsg', u'扫码推事件且弹出“消息接收中”提示框'), ('pic_sysphoto', u'弹出系统拍照发图'), ('pic_photo_or_album', u'弹出拍照或者相册发图'), ('pic_weixin', u'弹出微信相册发图器'), ('location_select', u'弹出地理位置选择器')], u'按钮的类型', required=True, default='xml') name = fields.Char(u'菜单标题', required=True) key = fields.Char(u'菜单KEY值') url = fields.Char(u'网页链接') @api.constrains('partner_menu_id', 'name') def _check_menu_name_length(self): if self.name and self.partner_menu_id and len(self.name) > 7: raise Warning(u'二级菜单显示名称不能超过14个字符或7个汉字.') elif self.name and not self.partner_menu_id and len(self.name) > 4: raise Warning(u'一级菜单显示名称不能超过8个字符或4个汉字.') else: return True @api.constrains('agentid') def check_menu_number(self): """ 取得一个app的一级菜单量 :return: """ menus_ids = self.sudo().search([('agentid', '=', self.agentid['name']), ('partner_menu_id', '=', False)]) if menus_ids and len(menus_ids) > 3: raise Warning(u'公众号的一级菜单数据不能超过3个.') return True @api.constrains('partner_menu_id') def check_submenu_number(self): """ 取得一个一级菜单的子菜单数量 :return: """ sub_menus_ids = self.sudo().search( [('partner_menu_id', '=', self.partner_menu_id['name']), ('partner_menu_id', '!=', False)]) if sub_menus_ids and len(sub_menus_ids) > 5: raise Warning(u'一级菜单的二级子菜单数据不能超过5个.') return True