From e905c282dfc8d54e686269bd16289f471c41fed5 Mon Sep 17 00:00:00 2001 From: pengyuthon Date: Sun, 18 Jan 2026 18:04:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8C=89=E9=92=AE=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/webclient/actions/client_actions.js | 39 +++++++- yuthon_wechat/models/wecom_apps.py | 98 +++++++++++++------ yuthon_will_task/models/yuthon_will_task.py | 21 +--- .../views/yuthon_will_task_views.xml | 2 +- 4 files changed, 112 insertions(+), 48 deletions(-) diff --git a/sun_badge_menu/static/src/webclient/actions/client_actions.js b/sun_badge_menu/static/src/webclient/actions/client_actions.js index 9036f0b1f..2d8e46fb8 100644 --- a/sun_badge_menu/static/src/webclient/actions/client_actions.js +++ b/sun_badge_menu/static/src/webclient/actions/client_actions.js @@ -25,6 +25,41 @@ async function flushBadge(env, action) { await env.services.action.restore(controller.jsId); } } - - registry.category("actions").add("flush_badge", flushBadge); + +const getWkfAction = (treeId, uid) => { + return { + name: '流程待办', + type: 'ir.actions.act_window', + res_model: 'soong.workflow.record', + views: [[treeId, 'tree']], + domain: [ + ['users_ids', 'in', uid], + ['reclaim_state', '=', false], + ['soong_state', '=', 'to_do'], + ], + context: { + header_search_default_approve_state: 1, + header_search_default_to_do: 1, + check_employee: 1 + } + } +} +async function flushBadgeWithWorkflow(env, action) { + await env.services.menu.reload(); + if (action && action.params && 'menu_id' in action.params) { + env.services.menu.setCurrentMenu(action.params.menu_id); + } + + // 跳转tree + const { tree_id, uid } = action.params; + if (tree_id && uid) { + return env.services.action.doAction(getWkfAction(tree_id, uid)); + } + + const controller = env.services.action.currentController; + if (controller) { + await env.services.action.restore(controller.jsId); + } +} +registry.category("actions").add("flush_badge_wkf", flushBadgeWithWorkflow); diff --git a/yuthon_wechat/models/wecom_apps.py b/yuthon_wechat/models/wecom_apps.py index 40953572d..a9bf0f1eb 100644 --- a/yuthon_wechat/models/wecom_apps.py +++ b/yuthon_wechat/models/wecom_apps.py @@ -342,46 +342,88 @@ class WeComApps(models.Model): return True, result_data return False, result_data.get("errmsg", "") + # @api.model + # def generate_oauth_login_url(self, target_url, category='default'): + # """ + # 生成企业微信OAuth登录链接,用于在企业微信消息中发送 + # + # 参数: + # target_url: 登录成功后要跳转的目标URL(完整URL或相对路径) + # + # 返回: + # OAuth登录链接URL + # """ + # base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') + # # 如果target_url不是完整URL,补全为完整URL + # if not target_url.startswith('http'): + # if target_url.startswith('/'): + # target_url = f"{base_url}{target_url}" + # else: + # target_url = f"{base_url}/{target_url}" + # # 编码目标URL作为state参数 + # encoded_target_url = quote(target_url, safe='') + # # 编码回调URI + # redirect_uri = quote(f'{base_url}/wechat/login_by_code', safe='') + # + # # 企业微信OAuth参数 + # if category == 'oa': + # agent_id = self.env['wecom.apps'].search([('name', '=', '审批消息通知')])['agent_id'] + # appid = self.env['wecom.apps'].search([('name', '=', '审批消息通知')])['corpid'] + # else: + # appid = 'wwc955c117b738b052' + # agent_id = '1000120' + # + # # 生成OAuth登录链接 + # oauth_url = ( + # f'https://open.weixin.qq.com/connect/oauth2/authorize?' + # f'appid={appid}&' + # f'redirect_uri={redirect_uri}&' + # f'response_type=code&' + # f'scope=snsapi_base&' + # f'state={encoded_target_url}&' + # f'agentid={agent_id}#wechat_redirect' + # ) + # + # return oauth_url + @api.model - def generate_oauth_login_url(self, target_url, category='default'): + def generate_oauth_login_url(self, target_url, user_id=None): """ - 生成企业微信OAuth登录链接,用于在企业微信消息中发送 - + + user_id = record.employee_id.user_id.id if record.employee_id.user_id else None + url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, user_id=user_id) + + 生成企业微信免登录链接,用于在企业微信消息中发送 + 与 /wechat/login_by_user_id 接口联动 + 参数: target_url: 登录成功后要跳转的目标URL(完整URL或相对路径) - + user_id: 用户ID (res.users的id),必需参数 + 返回: - OAuth登录链接URL + 免登录链接URL,格式: /wechat/login_by_user_id?user_id=xxx&redirect_url=xxx """ + if not user_id: + _logger.warning("generate_oauth_login_url: user_id 参数未提供,无法生成免登录链接") + return target_url # 如果未提供user_id,返回原始URL + base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') + # 如果target_url不是完整URL,补全为完整URL if not target_url.startswith('http'): if target_url.startswith('/'): target_url = f"{base_url}{target_url}" else: target_url = f"{base_url}/{target_url}" - # 编码目标URL作为state参数 + + # 编码目标URL作为redirect_url参数 encoded_target_url = quote(target_url, safe='') - # 编码回调URI - redirect_uri = quote(f'{base_url}/wechat/login_by_code', safe='') - - # 企业微信OAuth参数 - if category == 'oa': - agent_id = self.env['wecom.apps'].search([('name', '=', '审批消息通知')])['agent_id'] - appid = self.env['wecom.apps'].search([('name', '=', '审批消息通知')])['corpid'] - else: - appid = 'wwc955c117b738b052' - agent_id = '1000120' - - # 生成OAuth登录链接 - oauth_url = ( - f'https://open.weixin.qq.com/connect/oauth2/authorize?' - f'appid={appid}&' - f'redirect_uri={redirect_uri}&' - f'response_type=code&' - f'scope=snsapi_base&' - f'state={encoded_target_url}&' - f'agentid={agent_id}#wechat_redirect' + + # 生成免登录链接,使用 /wechat/login_by_user_id 接口 + login_url = ( + f'{base_url}/wechat/login_by_user_id?' + f'user_id={user_id}&' + f'redirect_url={encoded_target_url}' ) - - return oauth_url + + return login_url diff --git a/yuthon_will_task/models/yuthon_will_task.py b/yuthon_will_task/models/yuthon_will_task.py index dfe4620be..901eb3e05 100644 --- a/yuthon_will_task/models/yuthon_will_task.py +++ b/yuthon_will_task/models/yuthon_will_task.py @@ -59,24 +59,11 @@ class YuthonWillTask(models.Model): is_this_company = fields.Boolean(string='本公司', default=True) task_state = fields.Selection([('will', '待办'), ('done', '已办'), ('cancel', '取消')], default='will', string='状态', store=True) - users_ids = fields.Many2many( - 'res.users', - relation='yuthon_will_task_users_rel', # - column1='task_id', - column2='user_id', - string='用户', - store=True, - index=True, - default=lambda self: self.env.user - ) + users_ids = fields.Many2many('res.users', relation='yuthon_will_task_users_rel', column1='task_id', column2='user_id', + string='用户', store=True, index=True, default=lambda self: self.env.user) - self_users_ids = fields.Many2many( - 'res.users', - relation='yuthon_will_task_current_users_rel', - column1='task_id', - column2='user_id', - string="当前经办人", - store=True, default=lambda self: [(6, 0, [self.env.user.id])] + self_users_ids = fields.Many2many('res.users', + relation='yuthon_will_task_current_users_rel',column1='task_id', column2='user_id', string="当前经办人", store=True, default=lambda self: [(6, 0, [self.env.user.id])] ) employee_id = fields.Many2one('hr.employee', string="经办人", default=lambda self: self.env.user.employee_id) diff --git a/yuthon_will_task/views/yuthon_will_task_views.xml b/yuthon_will_task/views/yuthon_will_task_views.xml index d2ee39c5a..72aea162a 100644 --- a/yuthon_will_task/views/yuthon_will_task_views.xml +++ b/yuthon_will_task/views/yuthon_will_task_views.xml @@ -24,7 +24,7 @@ -