!7158 添加功能

Merge pull request !7158 from 李鹏宇/dev_zhou
This commit is contained in:
李鹏宇
2025-12-19 07:39:58 +00:00
committed by Gitee
44 changed files with 0 additions and 419 deletions
@@ -1,4 +0,0 @@
# -*- coding: utf-8 -*-
from . import controllers
from . import models
@@ -1,21 +0,0 @@
# -*- coding: utf-8 -*-
{
'name': '模型测试',
'summary': '',
'description': '',
'author': 'XSK',
'website': '',
'category': 'Uncategorized',
'version': '0.1',
'license': 'LGPL-3',
'depends': ['base', 'web', 'mail'],
'data': [
'security/ir.model.access.csv',
'views/views.xml',
],
'assets': {
'web.assets_backend': [
'model_test/static/src/**/*',
],
},
}
@@ -1,3 +0,0 @@
# -*- coding: utf-8 -*-
from . import controllers
@@ -1,21 +0,0 @@
# -*- coding: utf-8 -*-
# from odoo import http
# class FilePreviewTest(http.Controller):
# @http.route('/file_preview_test/file_preview_test', auth='public')
# def index(self, **kw):
# return "Hello, world"
# @http.route('/file_preview_test/file_preview_test/objects', auth='public')
# def list(self, **kw):
# return http.request.render('file_preview_test.listing', {
# 'root': '/file_preview_test/file_preview_test',
# 'objects': http.request.env['file_preview_test.file_preview_test'].search([]),
# })
# @http.route('/file_preview_test/file_preview_test/objects/<model("file_preview_test.file_preview_test"):obj>', auth='public')
# def object(self, obj, **kw):
# return http.request.render('file_preview_test.object', {
# 'object': obj
# })
@@ -1,3 +0,0 @@
# -*- coding: utf-8 -*-
from . import models
@@ -1,211 +0,0 @@
# -*- coding: utf-8 -*-
from datetime import datetime, date, timedelta
import string
import random
from odoo import models, fields, api
class ModelTestManyOne(models.Model):
_name = 'model.test.many.one'
_description = '测试模块'
_inherit = ['mail.thread', 'mail.activity.mixin']
name = fields.Char(string='字符串字段', tracking=True)
test_id = fields.Many2one(string='多对一字段', comodel_name='model.test', required=True, ondelete='cascade')
file_id = fields.Many2one(string='多对一文件', comodel_name='ir.attachment', tracking=True)
file_ids = fields.Many2many(string='多对多文件', comodel_name='ir.attachment', relation='file_preview_test_many_one_rel', column1='test_id', column2='test_id_2')
class ModelTest(models.Model):
_name = 'model.test'
_description = '测试模块'
_inherit = ['mail.thread', 'mail.activity.mixin']
name = fields.Char(string='字符串字段', tracking=True)
int_field = fields.Integer(string='整数', tracking=True)
float_field = fields.Float(string='浮点数', tracking=True)
date_field = fields.Date(string='日期字段', tracking=True)
datetime_field = fields.Datetime(string='日期时间字段', tracking=True)
state = fields.Selection(string='状态', selection=[('draft', '草稿'), ('done', '完成')], default='draft')
file_id = fields.Many2one(string='多对一文件', comodel_name='ir.attachment')
file_ids = fields.Many2many(string='多对多文件', comodel_name='ir.attachment', relation='file_preview_test_rel', column1='test_id', column2='test_id_2')
text = fields.Text(string='长文本测试')
one_to_many_field = fields.One2many(string='one2many字段', comodel_name='model.test.many.one', inverse_name='test_id', tracking=True)
bool_test = fields.Boolean(string='布尔字段')
selection_test = fields.Selection(string='选择字段', selection=[('1', '选项一'), ('2', '选项二')])
def action_generate_sample_text(self):
"""生成长文本样例"""
sample_text = """
# 这是Markdown格式的样例文本
## 项目概述
这是一个测试项目,用于展示Odoo中各种字段类型的功能和显示效果。
### 功能特点
1. 支持多种数据类型
2. 自动生成测试数据
3. 便于开发和测试
### 技术规格
- 数据库:PostgreSQL
- 框架:Odoo 14.0+
- 语言:Python/XML/JavaScript
---
**注意**:此内容为自动生成,仅用于测试目的。
"""
self.write({'text': sample_text})
# 辅助方法
def _generate_random_string(self, length):
"""生成随机字符串"""
letters = string.ascii_letters + string.digits
return ''.join(random.choice(letters) for _ in range(length))
def _generate_random_date(self):
"""生成随机日期(最近365天内)"""
days_ago = random.randint(0, 365)
return date.today() - timedelta(days=days_ago)
def _generate_random_datetime(self):
"""生成随机日期时间(最近30天内)"""
hours_ago = random.randint(0, 720) # 30天*24小时
return datetime.now() - timedelta(hours=hours_ago)
# 生成随机数据的方法
def action_insert_random_data(self):
"""生成50条随机测试数据"""
# 预先生成一些附件供选择
attachment_ids = self.env['ir.attachment'].search([], limit=10)
for i in range(50):
# 生成随机数据
random_name = f"测试项目_{i + 1}_{self._generate_random_string(6)}"
random_int = random.randint(1, 1000)
random_float = round(random.uniform(1.0, 10000.0), 2)
random_date = self._generate_random_date()
random_datetime = self._generate_random_datetime()
random_state = random.choice(['draft', 'done'])
random_selection = random.choice(['1', '2'])
random_bool = random.choice([True, False])
# 生成随机文本
random_text = f"""
这是第{i + 1}条测试记录的长文本内容。
生成时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
随机ID:{self._generate_random_string(10)}
描述:这是一条自动生成的测试数据,用于演示各种字段类型的显示效果。
"""
# 创建主记录
test_record = self.create({
'name': random_name,
'int_field': random_int,
'float_field': random_float,
'date_field': random_date,
'datetime_field': random_datetime,
'state': random_state,
'bool_test': random_bool,
'selection_test': random_selection,
'text': random_text,
})
# 随机选择附件
if attachment_ids:
# 随机选择1-3个附件
num_attachments = random.randint(1, min(3, len(attachment_ids)))
random_attachments = random.sample(attachment_ids.ids, num_attachments)
test_record.write({
'file_id': random.choice(attachment_ids).id if attachment_ids else False,
'file_ids': [(6, 0, random_attachments)]
})
# 返回成功消息
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': '数据生成成功',
'message': f'已成功生成50条测试数据!',
'type': 'success',
'sticky': False,
'next': {'type': 'ir.actions.act_window_close'},
}
}
def action_to_dialog(self):
self.ensure_one()
return {
'type': 'ir.actions.act_window',
'res_model': 'model.test',
'view_mode': 'form',
'res_id': self.id,
'views': [[self.env.ref('model_test.view_file_preview_test_form').id, 'form']],
}
def cancel(self):
self.state = 'done'
def test_approval(self):
self.verify_rules(self.cancel)
# print(asd)
# class TimeCalculation(models.Model):
# _name = 'example.time.calculation'
# _description = 'Example for Start Time, End Time, Duration'
#
# start_time = fields.Datetime(string='Start Time', required=True)
# end_time = fields.Datetime(string='End Time', required=True)
# duration = fields.Float(string='Duration (hours)', compute='_compute_duration', inverse='_inverse_duration', store=True)
#
# @api.depends('start_time', 'end_time')
# def _compute_duration(self):
# """根据开始时间和结束时间计算时间间隔"""
# for record in self:
# if record.start_time and record.end_time:
# delta = record.end_time - record.start_time
# record.duration = delta.total_seconds() / 3600 # 转换为小时
#
# @api.depends('start_time', 'duration')
# def _compute_end_time(self):
# """根据开始时间和时间间隔计算结束时间"""
# for record in self:
# if record.start_time and record.duration is not None:
# record.end_time = record.start_time + timedelta(hours=record.duration)
#
# @api.depends('end_time', 'duration')
# def _compute_start_time(self):
# """根据结束时间和时间间隔计算开始时间"""
# for record in self:
# if record.end_time and record.duration is not None:
# record.start_time = record.end_time - timedelta(hours=record.duration)
#
# def _inverse_duration(self):
# """反向更新结束时间"""
# for record in self:
# if record.start_time and record.duration is not None:
# record.end_time = record.start_time + timedelta(hours=record.duration)
#
# @api.onchange('start_time', 'end_time')
# def _onchange_duration(self):
# """确保在界面交互中,时间关系自动更新"""
# for record in self:
# if record.start_time and record.end_time:
# delta = record.end_time - record.start_time
# record.duration = delta.total_seconds() / 3600
#
# @api.onchange('start_time', 'duration')
# def _onchange_end_time(self):
# """确保在界面交互中,时间关系自动更新"""
# for record in self:
# if record.start_time and record.duration is not None:
# record.end_time = record.start_time + timedelta(hours=record.duration)
#
# @api.onchange('end_time', 'duration')
# def _onchange_start_time(self):
# """确保在界面交互中,时间关系自动更新"""
# for record in self:
# if record.end_time and record.duration is not None:
# record.start_time = record.end_time - timedelta(hours=record.duration)
@@ -1,3 +0,0 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_model_test,测试模块,model_model_test,,1,1,1,1
access_model_test_many_one,测试模块多,model_model_test_many_one,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_model_test 测试模块 model_model_test 1 1 1 1
3 access_model_test_many_one 测试模块多 model_model_test_many_one 1 1 1 1
@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<templates id="template" xml:space="preserve">
<t t-name="ModelTest.buttons" t-inherit="web.ListView.Buttons" owl="1">
<xpath expr="(//div/*)[last()]" position="after">
<button type="button" class="btn btn-primary"
t-on-click="(ev) => this.triggerDynamicColumnsChanged('btn_1', ['name','int_field','float_field'])">
方案1
</button>
<button type="button" class="btn btn-primary"
t-on-click="(ev) => this.triggerDynamicColumnsChanged('btn_2', ['selection_test','text','one_to_many_field'])">
方案2
</button>
</xpath>
</t>
</templates>
@@ -1,10 +0,0 @@
/** @odoo-module **/
import { registry } from '@web/core/registry';
import { listView } from '@web/views/list/list_view';
export const ModelTestListView = {
...listView,
buttonTemplate: 'ModelTest.buttons'
};
registry.category('views').add('model_test_list', ModelTestListView);
@@ -1,126 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>
<!-- 项目总览搜索 -->
<record id="view_model_test_search_view" model="ir.ui.view">
<field name="model">model.test</field>
<field name="arch" type="xml">
<search string="项目总览">
<separator/>
<filter string="真" name="filter_by_true" domain="[('bool_test', '=', True)]"/>
<separator/>
<filter string="假" name="filter_by_false" domain="[('bool_test', '=', False)]"/>
<group expand="0" string="Group By">
<filter string="多对一未见" name="group_by_file_id" domain="[]" context="{'group_by': 'file_id'}" />
<filter string="布尔值" name="group_by_bool_test" domain="[]" context="{'group_by': 'bool_test'}" />
</group>
<searchpanel>
<field name="file_id"/>
</searchpanel>
<!--
<header_search class="header-search-inline"> 所有搜索在一行
-->
<header_search>
<field name="name"/>
<field name="file_id"/>
<field name="selection_test" options="{'radio': True}"/>
<field name="bool_test" options="{'radio': True, 'no_label': True}"/>
<select_date_filter allow_date_fields="create_date,write_date" />
<quick_filter string="快捷筛选一" options="{'radio': True, 'no_label': True}">
<filter string="真" name="filter_by_bool_true" domain="[('bool_test', '=', True)]"/>
<filter string="最近的二十" name="filter_by_bool_true"/>
</quick_filter>
<field name="date_field" options="{'radio': True, 'no_label': True}"/>
<field name="datetime_field"/>
<quick_filter string="快捷筛选二" options="{'radio': True, 'no_label': True}">
<filter string="假" name="filter_by_bool_false" domain="[('bool_test', '=', False)]"/>
</quick_filter>
</header_search>
</search>
</field>
</record>
<!-- tree视图 -->
<record id="view_model_test_tree" model="ir.ui.view">
<field name="name">model.test.tree</field>
<field name="model">model.test</field>
<field name="arch" type="xml">
<tree string="">
<header>
<button name="action_insert_random_data" string="随机插入50条数据" type="object" class="btn-primary ms-1" display="always"/>
</header>
<field name="name"/>
<field name="int_field"/>
<field name="float_field"/>
<field name="selection_test"/>
<field name="text" widget="text_nowrap"/>
<field name="one_to_many_field"/>
<field name="state"/>
</tree>
</field>
</record>
<!-- form视图 -->
<record id="view_model_test_form" model="ir.ui.view">
<field name="name">model.test.form</field>
<field name="model">model.test</field>
<field name="arch" type="xml">
<form string="Job">
<header>
<button string="测试审批" type="object" name="test_approval" class="btn-primary"/>
</header>
<sheet>
<group>
<field name="name"/>
<field name="int_field"/>
<field name="float_field"/>
<field name="date_field"/>
<field name="datetime_field"/>
<field name="state"/>
<field name="text"/>
<field name="file_id"/>
<field name="selection_test"/>
<field name="bool_test" widget="boolean_toggle"/>
<field name="file_ids"/>
</group>
<notebook>
<page string="多对多字段图片预览测试">
<field name="file_ids"/>
</page>
<page string="one2many字段">
<field name="one_to_many_field" mode="tree">
<tree editable="1">
<field name="name"/>
<field name="file_id"/>
<field name="file_ids"/>
</tree>
</field>
</page>
</notebook>
</sheet>
<!-- Attachment preview -->
<div class="o_attachment_preview" groups="hr_recruitment.group_applicant_cv_display"/>
<div class="oe_chatter">
<field name="message_ids"/>
</div>
</form>
</field>
</record>
<!-- 跳转菜单 -->
<record model="ir.actions.act_window" id="file_preview_menu_action_window">
<field name="name">文件测试</field>
<field name="target">main</field>
<field name="res_model">model.test</field>
<field name="view_mode">tree,form</field>
</record>
<!-- 二级菜单 -->
<menuitem
id="model_test_menu"
name="测试模块"
sequence="10"
action="file_preview_menu_action_window"/>
</data>
</odoo>