move and update gpt

This commit is contained in:
ivan deng
2023-02-16 22:37:14 +08:00
parent 9752fd7f6d
commit 3477d98a53
32 changed files with 554 additions and 18 deletions

5
app_chatgpt/__init__.py Normal file
View File

@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-Present InTechual Solutions. (<https://intechualsolutions.com/>)
# from . import controllers
from . import models

View File

@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
# Created on 2023-02-016
# author: 广州尚鹏https://www.sunpop.cn
# email: 300883@qq.com
# resource of Sunpop
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# Copyright (c) 2020-Present InTechual Solutions. (<https://intechualsolutions.com/>)
{
'name': 'ChatGPT Robot Multi Chat and Training(Under Construction)',
'version': '16.23.02.15',
'author': 'Sunpop.cn',
'company': 'Sunpop.cn',
'maintainer': 'Sunpop.cn',
'category': 'Website/Website',
'website': 'https://www.sunpop.cn',
'license': 'LGPL-3',
'sequence': 10,
'license': 'AGPL-3',
'summary': '''
Multi Odoo ChatGPT Robot. Integration All ChatGpt Api.
Chat channel with several ChatGPT Robots.
Whitelist and blacklist for Users or IP.
Base on is_chatgpt_integration from InTechual Solutions.
''',
'description': '''
Allows the application to leverage the capabilities of the GPT language model to generate human-like responses,
providing a more natural and intuitive user experience.
1. Multi ChatGpt robot Connector. Chat and train.
2. Multi User Chat with ChatGpt
3. ChatGpt Channel for Group Chat
4. White and black List for ChatGpt
5. Demo Chat time for new user
6. Easy Start and Stop ChatGpt
''',
'depends': ['base', 'base_setup', 'mail'],
'data': [
'data/mail_channel_data.xml',
'data/user_partner_data.xml',
'data/ir_config_parameter.xml',
'views/res_config_settings_views.xml',
],
'external_dependencies': {'python': ['openai']},
'images': ['static/description/banner.png'],
'installable': True,
'application': False,
'auto_install': False,
}

View File

@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-Present InTechual Solutions. (<https://intechualsolutions.com/>)
from . import main

View File

@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-Present InTechual Solutions. (<https://intechualsolutions.com/>)
from odoo import http
class ChatgptController(http.Controller):
@http.route(['/chatgpt_form'], type='http', auth="public", csrf=False,
website=True)
def question_submit(self):
return http.request.render('app_chatgpt.connector')

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="config_openapi_context_timeout" model="ir.config_parameter">
<field name="key">app_chatgpt.openapi_context_timeout</field>
<field name="value">600</field>
</record>
</data>
</odoo>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record model="mail.channel" id="channel_chatgpt">
<field name="name">ChatGPT群聊</field>
<field name="description">ChatGPT企业内部频道</field>
<field name="image_128" type="base64" file="app_chatgpt/static/description/chatgpt.png"/>
</record>
<record model="mail.message" id="module_install_notification">
<field name="model">mail.channel</field>
<field name="res_id" ref="app_chatgpt.channel_chatgpt"/>
<field name="message_type">email</field>
<field name="subtype_id" ref="mail.mt_comment"/>
<field name="subject">欢迎来到ChatGPT的odoo群聊频道!</field>
<field name="body"><![CDATA[<p>欢迎进行 #ChatGPT 群聊.</p>
<p>向ChatGPT咨询你的问题</b>.</p>]]></field>
</record>
<record model="mail.channel.member" id="channel_member_chatgtp_channel_for_admin">
<field name="partner_id" ref="base.partner_admin"/>
<field name="channel_id" ref="app_chatgpt.channel_chatgpt"/>
<field name="fetched_message_id" ref="app_chatgpt.module_install_notification"/>
<field name="seen_message_id" ref="app_chatgpt.module_install_notification"/>
</record>
<record model="mail.channel" id="app_chatgpt.channel_chatgpt">
<field name="group_ids" eval="[Command.link(ref('base.group_user'))]"/>
</record>
</data>
</odoo>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="partner_chatgpt" model="res.partner">
<field name="name">ChatGPT的odoo机器人</field>
<field name="image_1920" type="base64" file="app_chatgpt/static/description/chatgpt.png"/>
</record>
<record id="user_chatgpt" model="res.users">
<field name="login">chatgpt@sunpop.cn</field>
<field name="password">chatgpt</field>
<field name="partner_id" ref="app_chatgpt.partner_chatgpt"/>
<field name="company_id" ref="base.main_company"/>
<field name="company_ids" eval="[Command.link(ref('base.main_company'))]"/>
<field name="groups_id" eval="[Command.link(ref('base.group_user'))]"/>
</record>
</data>
</odoo>

View File

@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-Present InTechual Solutions. (<https://intechualsolutions.com/>)
from . import mail_channel
from . import res_config_settings

View File

@@ -0,0 +1,145 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-Present InTechual Solutions. (<https://intechualsolutions.com/>)
import openai
import requests,json
import datetime
from odoo import api, fields, models, _
from odoo.exceptions import UserError
import logging
_logger = logging.getLogger(__name__)
class Channel(models.Model):
_inherit = 'mail.channel'
@api.model
def get_openai(self, api_key, data, user="Odoo"):
headers = {"Content-Type": "application/json", "Authorization": f"Bearer {api_key}"}
pdata = {
"model": "text-davinci-003",
"prompt": data,
"temperature": 0.9,
"max_tokens": 1000,
"top_p": 1,
"frequency_penalty": 0.0,
"presence_penalty": 0.6,
"user": user,
"stop": ["Human:", "AI:"]
}
response = requests.post("https://api.openai.com/v1/completions", data=json.dumps(pdata), headers=headers)
res = response.json()
if 'choices' in res:
return '\n'.join([x['text'] for x in res['choices']])
_logger.error(res)
return "获取结果超时,请重新跟我聊聊。"
@api.model
def get_openai_context(self, channel_id, partner_chatgpt, current_prompt,seconds=600):
afterTime = fields.Datetime.now() - datetime.timedelta(seconds=seconds)
message_model = self.env['mail.message'].sudo()
prompt = [f"Human:{current_prompt}\nAI:", ]
domain = [('res_id', '=', channel_id),
('model', '=', 'mail.channel'),
('message_type', '!=', 'user_notification'),
('parent_id', '=', False),
('date', '>=', afterTime),
('author_id', '=', self.env.user.partner_id.id)]
messages = message_model.with_context(tz='UTC').search(domain, order="id desc", limit=15)
# print('domain:',domain)
# print('messages:',messages)
for msg in messages:
ai_msg = message_model.search([("res_id", "=", channel_id),
('model', '=', msg.model),
('parent_id', '=', msg.id),
('author_id', '=', partner_chatgpt),
('body', '!=', '<p>获取结果超时,请重新跟我聊聊。</p>')])
if ai_msg:
prompt.append("Human:%s\nAI:%s" % (
msg.body.replace("<p>", "").replace("</p>", ""), ai_msg.body.replace("<p>", "").replace("</p>", "")))
# print(msg.body.replace("<p>", "").replace("</p>", ""))
# print(ai_msg.body.replace("<p>", "").replace("</p>", ""))
else:
_logger.error(f"not find for id:{str(msg.id)}")
return '\n'.join(prompt[::-1])
def get_chatgpt_answer(self,prompt,partner_name):
response = openai.Completion.create(
model="text-davinci-003",
prompt=prompt,
temperature=0.6,
max_tokens=3000,
top_p=1,
frequency_penalty=0,
presence_penalty=0,
user=partner_name,
)
res = response['choices'][0]['text']
return res
def _notify_thread(self, message, msg_vals=False, **kwargs):
rdata = super(Channel, self)._notify_thread(message, msg_vals=msg_vals, **kwargs)
# print(f'rdata:{rdata}')
chatgpt_channel_id = self.env.ref('app_chatgpt.channel_chatgpt')
user_chatgpt = self.env.ref("app_chatgpt.user_chatgpt")
partner_chatgpt = self.env.ref("app_chatgpt.partner_chatgpt")
author_id = msg_vals.get('author_id')
# print('author_id:',author_id)
# print('partner_chatgpt.id:',partner_chatgpt.id)
chatgpt_name = str(partner_chatgpt.name or '') + ', '
# print('chatgpt_name:', chatgpt_name)
prompt = msg_vals.get('body')
# print('prompt:', prompt)
# print('-----')
if not prompt:
return rdata
api_key = self.env['ir.config_parameter'].sudo().get_param('app_chatgpt.openapi_api_key')
try:
openapi_context_timeout = int(self.env['ir.config_parameter'].sudo().get_param('app_chatgpt.openapi_context_timeout')) or 600
except:
openapi_context_timeout = 600
openai.api_key = api_key
Partner = self.env['res.partner']
partner_name = ''
if author_id:
partner_id = Partner.browse(author_id)
if partner_id:
partner_name = partner_id.name
# print(msg_vals)
# print(msg_vals.get('record_name', ''))
# print('self.channel_type :',self.channel_type)
if author_id != partner_chatgpt.id and (chatgpt_name in msg_vals.get('record_name', '') or 'ChatGPT,' in msg_vals.get('record_name', '') ) and self.channel_type == 'chat':
_logger.info(f'私聊:author_id:{author_id},partner_chatgpt.id:{partner_chatgpt.id}')
try:
channel = self.env[msg_vals.get('model')].browse(msg_vals.get('res_id'))
prompt = self.get_openai_context(channel.id, partner_chatgpt.id, prompt,openapi_context_timeout)
print(prompt)
# res = self.get_chatgpt_answer(prompt,partner_name)
res = self.get_openai(api_key, prompt, partner_name)
# print('res:',res)
# print('channel:',channel)
channel.with_user(user_chatgpt).message_post(body=res, message_type='comment',subtype_xmlid='mail.mt_comment',parent_id=message.id)
# channel.with_user(user_chatgpt).message_post(body=res, message_type='notification', subtype_xmlid='mail.mt_comment')
# channel.sudo().message_post(
# body=res,
# author_id=partner_chatgpt.id,
# message_type="comment",
# subtype_xmlid="mail.mt_comment",
# )
# self.with_user(user_chatgpt).message_post(body=res, message_type='comment', subtype_xmlid='mail.mt_comment')
except Exception as e:
raise UserError(_(e))
elif author_id != partner_chatgpt.id and msg_vals.get('model', '') == 'mail.channel' and msg_vals.get('res_id', 0) == chatgpt_channel_id.id:
_logger.info(f'频道群聊:author_id:{author_id},partner_chatgpt.id:{partner_chatgpt.id}')
try:
prompt = self.get_openai_context(chatgpt_channel_id.id, partner_chatgpt.id, prompt,openapi_context_timeout)
# print(prompt)
# res = self.get_chatgpt_answer(prompt, partner_name)
res = self.get_openai(api_key, prompt, partner_name)
chatgpt_channel_id.with_user(user_chatgpt).message_post(body=res, message_type='comment', subtype_xmlid='mail.mt_comment',parent_id=message.id)
except Exception as e:
raise UserError(_(e))
return rdata

View File

@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020-Present InTechual Solutions. (<https://intechualsolutions.com/>)
from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"
openapi_api_key = fields.Char(string="API Key", help="Provide the API key here", config_parameter="app_chatgpt.openapi_api_key")
openapi_context_timeout = fields.Integer(string="上下文连接超时", help="多少秒以内的聊天信息作为上下文继续", config_parameter="app_chatgpt.openapi_context_timeout")

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@@ -0,0 +1,176 @@
<section class="oe_container">
<div class="oe_row oe_spaced">
<h1 class="oe_slogan" style="color:#875A7B;">ChatGPT Robot Multi Chat and Training(Under Construction)</h1>
<h2 class="oe_slogan" style="color:#875A7B;">Base on Integrate Odoo with ChatGPT from InTechual Solutions</h2>
<h3 class="oe_slogan">Allows the application to leverage the capabilities of the GPT language model to generate human-like responses, providing a more natural and intuitive user experience
</h3>
<div class="oe_demo oe_picture oe_screenshot">
<img src="main_screenshot.png">
</div>
</div>
</section>
<br/>
<br/>
<section class="oe_container oe_mt32">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan" style="color:#875A7B;">Configure ChatGPT API Key</h2>
<h3 class="oe_slogan">Get your OpenAPI API Key</h3>
<div class="oe_span12">
<p class="oe_mt32 oe_mb32 text-justify">Get your OpenAPI API Key from: <a href="https://platform.openai.com/account/api-keys">https://platform.openai.com/account/api-keys</a></p>
<div class="oe_demo oe_picture oe_screenshot">
<img class='img-responsive' src="api_key.png">
</div>
</div>
</div>
</section>
<br/>
<br/>
<section class="oe_container oe_mt32">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan" style="color:#875A7B;">Get Best from ChatGPT</h2>
<div class="oe_span12">
<p class="oe_mt32 oe_mb32 text-justify">Give your promts to ChatGPT and get best out of AI.</p>
<div class="oe_demo oe_picture oe_screenshot">
<img class='img-responsive' src="chatgpt_chat.png">
</div>
</div>
</div>
</section>
<br/>
<br/>
<section class="oe_container oe_mt32">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan" style="color:#875A7B;">Requirements</h2>
<div class="oe_span12">
<p class="oe_mt32 oe_mb32">
<strong>openai</strong> python library - <br/><code>sudo python3 -m pip install openai</code>
<br/>
- OR -
<br/>
<code>pip install openai</code>
Note: Contact us if you find any difficulties in setup/installation.
</p>
</div>
</div>
</section>
<br/>
<br/>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h4 class="oe_slogan"> <a href="https://youtu.be/KwkWk4terrs" target="_blank" style="color: #FFFFFF !important; border-radius: 0; background-color: #f05c4e; border-color: #005ca7; padding: 15px; font-weight: bold;">
<i class="fa fa-youtube"></i>
Watch on YouTube
</a></h4>
<center>
</center>
</div>
</div>
</section>
<section class="oe_container">
<h2 class="oe_slogan" style="color:#875A7B;">Our other apps you may like!</h2>
<div id="slides" class="row carousel slide mt64 mb32" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active" style="min-height: 0px;">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
<a href="https://apps.odoo.com/apps/modules/16.0/whatsapp_all_in_one" target="_blank">
<div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;">
<img class="img img-responsive center-block" style="border-top-left-radius: 10px; width: 360px; height: 180px; border-top-right-radius: 10px;" src="wp_all_in_one.gif">
<h4 class="mt0" style="padding:6% 4%;text-align: center;white-space: nowrap;width: 100%;overflow: hidden;text-overflow: ellipsis;font-family: Roboto-medium;">
WhatsApp All In One
</h4>
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
<a href="https://apps.odoo.com/apps/modules/16.0/whatsapp_sale_integration" target="_blank">
<div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;">
<img class="img img-responsive center-block"
style="border-top-left-radius: 10px; width: 360px; height: 180px; border-top-right-radius: 10px;"
src="whatsapp_sale_integration.png"/>
<h4 class="mt0" style="padding:6&#37; 4&#37;;text-align: center;white-space: nowrap;width: 100&#37;;overflow: hidden;text-overflow: ellipsis;font-family: Roboto-medium;">
WhatsApp Delivery Integration
</h4>
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
<a href="https://apps.odoo.com/apps/modules/16.0/whatsapp_invoice_integration" target="_blank">
<div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;">
<img class="img img-responsive center-block"
style="border-top-left-radius: 10px; width: 360px; height: 180px; border-top-right-radius: 10px;"
src="whatsapp_invoice_integration.png"/>
<h4 class="mt0" style="padding:6&#37; 4&#37;;text-align: center;white-space: nowrap;width: 100&#37;;overflow: hidden;text-overflow: ellipsis;font-family: Roboto-medium;">
WhatsApp Invoice Integration
</h4>
</div>
</a>
</div>
</div>
<div class="carousel-item">
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
<a href="https://apps.odoo.com/apps/modules/16.0/whatsapp_pos_integration" target="_blank">
<div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;">
<img class="img img-responsive center-block"
style="border-top-left-radius: 10px; width: 360px; height: 180px; border-top-right-radius: 10px;"
src="whatsapp_pos_integration.png"/>
<h4 class="mt0" style="padding:6&#37; 4&#37;;text-align: center;white-space: nowrap;width: 100&#37;;overflow: hidden;text-overflow: ellipsis;font-family: Roboto-medium;">
WhatsApp PoS Integration
</h4>
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
<a href="https://apps.odoo.com/apps/modules/16.0/whatsapp_purchase_integration" target="_blank">
<div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;">
<img class="img img-responsive center-block"
style="border-top-left-radius: 10px; width: 360px; height: 180px; border-top-right-radius: 10px;"
src="whatsapp_purchase_integration.png"/>
<h4 class="mt0" style="padding:6&#37; 4&#37;;text-align: center;white-space: nowrap;width: 100&#37;;overflow: hidden;text-overflow: ellipsis;font-family: Roboto-medium;">
WhatsApp Purchase Integration
</h4>
</div>
</a>
</div>
<div class="col-xs-12 col-sm-4 col-md-4 mb16 mt16" style="float: left;">
<a href="https://apps.odoo.com/apps/modules/16.0/whatsapp_payment_integration" target="_blank">
<div style="box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07);border-radius: 10px;">
<img class="img img-responsive center-block"
style="border-top-left-radius: 10px; width: 360px; height: 180px; border-top-right-radius: 10px;"
src="whatsapp_payment_integration.png"/>
<h4 class="mt0" style="padding:6&#37; 4&#37;;text-align: center;white-space: nowrap;width: 100&#37;;overflow: hidden;text-overflow: ellipsis;font-family: Roboto-medium;">
WhatsApp Payments Integration
</h4>
</div>
</a>
</div>
</div>
</div>
<a class="carousel-control-prev" href="#slides" data-slide="prev" style="left:-25px;width: 35px;color: #000;">
<span class="carousel-control-prev-icon"><i class="fa fa-chevron-left" style="font-size:24px"></i></span>
</a>
<a class="carousel-control-next" href="#slides" data-slide="next" style="right:-25px;width: 35px;color: #000;">
<span class="carousel-control-next-icon"><i class="fa fa-chevron-right" style="font-size:24px"></i></span>
</a>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan" style="color:#875A7B;">Support</h2>
<p class="text-center">
<a href="https://intechualsolutions.com" target="_blank" style="font-weight:bold; font-size:30px; color:#777 !important"><img class="img img-responsive center-block"
style="border-top-left-radius: 10px; width: 360px; height: 115px; border-top-right-radius: 10px;" src="logo.png"/></a>
</p>
<p class="oe_slogan">
Please contact us if you need customization/support for this module <a href="mailto:info@intechualsolutions.com">info@intechualsolutions.com</a>
</p>
<p class="text-center">
<a class="btn btn-success mt8" title="Website" style="background-color: #ff824c; color: #FFFFFF !important;" href="https://intechualsolutions.com" target="_blank"> https://intechualsolutions.com </a>
<a class="btn btn-success mt8" title="Website" style="background-color: #3b406d; color: #FFFFFF !important;" href="mailto:info@intechualsolutions.com"> Support </a><br/><br/>
<span>Note: We have changed our company name from <b>Ascents Entrepreneurs</b> to <b>InTechual Solutions</b></span>
</p>
</div>
</div>
</section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 KiB

View File

@@ -0,0 +1,30 @@
<?xml version="1.0"?>
<odoo>
<record id="is_res_config_settings_view" model="ir.ui.view">
<field name="name">res.config.settings.view.form.is.chatgpt.inherit</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="base_setup.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='integration']" position="after">
<h2>ChatGPT</h2>
<div class="col-xs-12 row o_settings_container" id="chatgpt_integraion">
<div class="col-xs-12 col-md-10 o_setting_box">
<div class="o_setting_right_pane border-start-0">
<div class="content-group">
<div class="row mt12">
<label class="col-lg-3" string="API Key" for="openapi_api_key"/>
<field name="openapi_api_key" title="OpenAPI API Key" style="width: 90% !important;" password="True"/>
</div>
<div class="row mt0">
<label class="col-lg-2" string="上下文连接超时" for="openapi_context_timeout"/>
<field name="openapi_context_timeout" title="上下文连接超时 秒数" style="width: 10% !important;"/>
</div>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>

View File

@@ -61,13 +61,17 @@
('before', 'web_enterprise/static/src/scss/primary_variables.scss', 'app_web_enterprise/static/src/scss/primary_variables.scss'),
],
'web.assets_backend': [
('after', 'web/static/src/views/**/*', 'app_web_enterprise/static/src/scss/views_style.scss'),
'app_web_enterprise/static/src/components/*/*.xml',
'app_web_enterprise/static/src/webclient/**/*.xml',
# 'app_web_enterprise/static/src/xml/base.xml',
],
# 这里是改样式,要 after处理
'web.assets_common': [
('after', 'web_enterprise/static/src/webclient/home_menu/home_menu_background.scss', 'app_web_enterprise/static/src/scss/home_menu_background.scss'),
],
'web.assets_frontend': [
# ('after', 'web/static/src/core/**/*', 'app_web_enterprise/static/src/xml/base.xml'),
('after', 'web_enterprise/static/src/webclient/home_menu/home_menu_background.scss', 'app_web_enterprise/static/src/scss/home_menu_background.scss'),
],
},

View File

@@ -0,0 +1,12 @@
//list 改标头背景
.o_list_renderer {
.o_list_table {
:not(.o_field_x2many_list) > & thead, tfoot {
tr > :not(:empty) {
padding-top: var(--ListRenderer-thead-padding-v);
padding-bottom: var(--ListRenderer-thead-padding-v);
background-color: $o-gray-100;
}
}
}
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="app_web_enterprise.EnterpriseNavBar" t-inherit="web_enterprise.EnterpriseNavBar" t-inherit-mode="extension">
<!-- todo: 以下主要是测试,改这个主图标为 O -->
<xpath expr="//a[hasclass('o_menu_toggle')]" position="replace">
<a href="#" class="o_menu_toggle fa fa-2x fa-opera" style="font-size: 2em;" accesskey="h" t-ref="menuApps" t-on-click.prevent="() => this.hm.toggle()">
<!-- <svg width="14px" height="14px" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg" >-->
<!-- <g t-foreach="[0, 5, 10]" t-as="Y" t-att-id="'o_menu_toggle_row_' + Y_index" fill="currentColor" t-key="'o_menu_toggle_row_' + Y_index">-->
<!-- <rect t-foreach="[0, 5, 10]" t-as="X" width="4" height="4" t-att-x="X" t-att-y="Y" t-key="'o_menu_toggle_cell_' + X_index"/>-->
<!-- </g>-->
<!-- </svg>-->
</a>
</xpath>
</t>
<!-- web.NavBar.SectionsMenu-->
<!-- 没有子菜单时调用web.DropdownItem-->
<!-- web.UserMenu-->
</templates>

View File

@@ -1,15 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-extend="HomeMenu.Content">
<t t-jquery=".o_home_menu_footer" t-operation="inner">
<img src='/web/binary/company_logo' alt="Logo"/>
</t>
</t>
<!-- 菜单有下拉箭头-->
<t t-inherit="web.Dropdown" t-inherit-mode="extension">
<!-- <t t-extend="HomeMenu.Content">-->
<!-- <t t-jquery=".o_home_menu_footer" t-operation="inner">-->
<!-- <img src='/web/binary/company_logo' alt="Logo"/>-->
<!-- </t>-->
<!-- </t>-->
<!-- 菜单有下拉箭头 owl的在 web.NavBar.SectionsMenu 有group的用 MenuDropdown 直接操作的用 DropdownItem -->
<t t-name="app_web_enterprise.Dropdown" t-inherit="web.Dropdown">
<xpath expr="//div[hasclass('o-dropdown')]" position="attributes">
<attribute name="t-att-class">{show: state.open}</attribute>
<attribute name="t-att-class">
{{ directionCaretClass || ''}}
{{ state.open ? 'show' : ''}}</attribute>
</xpath>
</t>

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-extend="res_config_edition">
<t t-jquery=".user-heading h3" t-operation="replace">
<h3>
odooApp <t t-esc="widget.server_version"/> (Sunpop.cn Edition)
</h3>
</t>
<t t-jquery=".user-o_web_settings_compact_subtitle small" t-operation="replace">
<small><a target="_blank" href="http://www.gnu.org/licenses/lgpl.html" style="text-decoration: underline;">GNU LGPL Licensed</a></small>
</t>
</t>
<!-- <t t-extend="res_config_edition">-->
<!-- <t t-jquery=".user-heading h3" t-operation="replace">-->
<!-- <h3>-->
<!-- odooApp <t t-esc="widget.server_version"/> (Sunpop.cn Edition)-->
<!-- </h3>-->
<!-- </t>-->
<!-- <t t-jquery=".user-o_web_settings_compact_subtitle small" t-operation="replace">-->
<!-- <small><a target="_blank" href="http://www.gnu.org/licenses/lgpl.html" style="text-decoration: underline;">GNU LGPL Licensed</a></small>-->
<!-- </t>-->
<!-- </t>-->
</templates>