From a4e067a05f213d0c5f34c6c69efc8f3bf49f24d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9C=E6=9C=AA=E5=A4=AE?= <2996985766@qq.com> Date: Sat, 25 Oct 2025 00:00:44 +0800 Subject: [PATCH] =?UTF-8?q?notebook=E5=A2=9E=E5=8A=A0=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E8=83=8C=E6=99=AF=E8=89=B2=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- estate/views/estate_property_views.xml | 2 +- issue/__init__.py | 1 + issue/__manifest__.py | 20 ++++++ issue/models/__init__.py | 3 + issue/models/issue_ticket.py | 50 +++++++++++++ issue/models/issue_ticket_detail.py | 18 +++++ issue/models/issue_ticket_tag.py | 9 +++ issue/security/ir.model.access.csv | 4 ++ issue/static/description/icon.png | Bin 0 -> 4261 bytes issue/static/description/icon.svg | 6 ++ issue/static/src/css/issue_styles.css | 8 +++ issue/static/src/version.js | 50 +++++++++++++ issue/static/src/version.xml | 13 ++++ issue/views/issue_ticket_menus.xml | 21 ++++++ issue/views/issue_ticket_views.xml | 94 +++++++++++++++++++++++++ 15 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 issue/__init__.py create mode 100644 issue/__manifest__.py create mode 100644 issue/models/__init__.py create mode 100644 issue/models/issue_ticket.py create mode 100644 issue/models/issue_ticket_detail.py create mode 100644 issue/models/issue_ticket_tag.py create mode 100644 issue/security/ir.model.access.csv create mode 100644 issue/static/description/icon.png create mode 100644 issue/static/description/icon.svg create mode 100644 issue/static/src/css/issue_styles.css create mode 100644 issue/static/src/version.js create mode 100644 issue/static/src/version.xml create mode 100644 issue/views/issue_ticket_menus.xml create mode 100644 issue/views/issue_ticket_views.xml diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index b4e255412..3d342e7db 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -16,7 +16,7 @@ - + diff --git a/issue/__init__.py b/issue/__init__.py new file mode 100644 index 000000000..9a7e03ede --- /dev/null +++ b/issue/__init__.py @@ -0,0 +1 @@ +from . import models \ No newline at end of file diff --git a/issue/__manifest__.py b/issue/__manifest__.py new file mode 100644 index 000000000..201ed5fd1 --- /dev/null +++ b/issue/__manifest__.py @@ -0,0 +1,20 @@ +{ + "name": "Issue Tracker", + "version": "17.0.1.0.0", + "summary": "内部问题追踪与处理", + "category": "Productivity", + "author": "Your Name", + "depends": ["base", "mail"], + "data": [ + "security/ir.model.access.csv", + "views/issue_ticket_views.xml", + "views/issue_ticket_menus.xml", + ], + "assets": { + "web.assets_backend": [ + "issue/static/src/**/*", + ], + }, + "installable": True, + "application": True, +} diff --git a/issue/models/__init__.py b/issue/models/__init__.py new file mode 100644 index 000000000..dd521f7f3 --- /dev/null +++ b/issue/models/__init__.py @@ -0,0 +1,3 @@ +from . import issue_ticket +from . import issue_ticket_tag +from . import issue_ticket_detail \ No newline at end of file diff --git a/issue/models/issue_ticket.py b/issue/models/issue_ticket.py new file mode 100644 index 000000000..aef2562ad --- /dev/null +++ b/issue/models/issue_ticket.py @@ -0,0 +1,50 @@ +from odoo import models, fields, api +from odoo.exceptions import ValidationError + + +class IssueTicket(models.Model): + _name = "issue.ticket" + _description = "问题单" + _inherit = ["mail.thread", "mail.activity.mixin"] + _order = "priority desc, create_date desc" + + name = fields.Char(string="问题标题", required=True, tracking=True) + description = fields.Text(string="问题描述") + reporter_id = fields.Many2one( + "res.users", string="报告人", default=lambda self: self.env.user + ) + assigned_id = fields.Many2one("res.users", string="负责人", tracking=True) + priority = fields.Selection( + [("0", "低"), ("1", "普通"), ("2", "高"), ("3", "紧急")], + default="1", + string="优先级", + tracking=True, + ) + state = fields.Selection( + [ + ("draft", "草稿"), + ("open", "已打开"), + ("in_progress", "处理中"), + ("done", "已解决"), + ("cancelled", "已取消"), + ], + default="draft", + string="状态", + tracking=True, + ) + deadline = fields.Date(string="截止日期") + tag_ids = fields.Many2many("issue.ticket.tag", string="标签") + work_end=fields.Boolean(string="工作结束", default=False, tracking=True) + remark=fields.Html(string="备注") + # 新增:问题明细关联 + line_ids = fields.One2many( + "issue.ticket.detail", "ticket_id", string="问题明细", copy=True + ) + + @api.constrains("deadline") + def _check_deadline(self): + for rec in self: + if rec.deadline and rec.deadline < fields.Date.today(): + raise ValidationError("截止日期不能早于今天。") + def action_set_draft(self): + self.state = "draft" diff --git a/issue/models/issue_ticket_detail.py b/issue/models/issue_ticket_detail.py new file mode 100644 index 000000000..d55b2f877 --- /dev/null +++ b/issue/models/issue_ticket_detail.py @@ -0,0 +1,18 @@ +from odoo import models, fields, api + +class IssueTicketDetail(models.Model): + _name = "issue.ticket.detail" + _description = "问题明细" + _order = "sequence, create_date" + + ticket_id = fields.Many2one( + "issue.ticket", string="问题单", required=True, ondelete="cascade", index=True + ) + sequence = fields.Integer(string="序号", default=10) + name = fields.Char(string="明细标题", required=True) + description = fields.Text(string="明细描述") + user_id = fields.Many2one("res.users", string="负责人", default=lambda self: self.env.user) + is_done = fields.Boolean(string="已完成", default=False) + planned_hours = fields.Float(string="预计小时数") + spent_hours = fields.Float(string="已用小时数") + note = fields.Html(string="备注") \ No newline at end of file diff --git a/issue/models/issue_ticket_tag.py b/issue/models/issue_ticket_tag.py new file mode 100644 index 000000000..925e64379 --- /dev/null +++ b/issue/models/issue_ticket_tag.py @@ -0,0 +1,9 @@ +from odoo import models, fields + + +class IssueTicketTag(models.Model): + _name = "issue.ticket.tag" + _description = "问题标签" + + name = fields.Char(string="标签名称", required=True) + color = fields.Integer(string="颜色") diff --git a/issue/security/ir.model.access.csv b/issue/security/ir.model.access.csv new file mode 100644 index 000000000..4b13b413c --- /dev/null +++ b/issue/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_issue_ticket_user,access.issue.ticket.user,model_issue_ticket,,1,1,1,1 +access_issue_ticket_tag_user,access.issue.ticket.tag.user,model_issue_ticket_tag,,1,1,1,1 +access_issue_ticket_detail_user,access.issue.ticket.detail.user,model_issue_ticket_detail,,1,1,1,1 diff --git a/issue/static/description/icon.png b/issue/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9c50d28255facfe802e525fde5127badc2dbf5b7 GIT binary patch literal 4261 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 + + + + + diff --git a/issue/static/src/css/issue_styles.css b/issue/static/src/css/issue_styles.css new file mode 100644 index 000000000..04743d6bd --- /dev/null +++ b/issue/static/src/css/issue_styles.css @@ -0,0 +1,8 @@ +.issue_ticket_detail_page td[name="name"] { + background-color: gray !important; + color: white !important; +} +.issue_ticket_detail_page td[name="name"]:hover { + background-color: black !important; + color: white !important; +} \ No newline at end of file diff --git a/issue/static/src/version.js b/issue/static/src/version.js new file mode 100644 index 000000000..90236ceba --- /dev/null +++ b/issue/static/src/version.js @@ -0,0 +1,50 @@ +/** @odoo-module **/ +import { Component } from "@odoo/owl"; +import { registry } from "@web/core/registry"; +import { useService } from "@web/core/utils/hooks"; + +export class Version extends Component { + static template = "base_foundation.version"; + static props = ["*"]; + + setup() { + this.actionService = useService("action"); + } + + async openDialog(size) { + const action = { + name: 'Mitchell Admin', + type: 'ir.actions.act_window', + res_model: 'res.users', + res_id: 2, + views: [[162, 'form']], + target: 'new', + context: { + dialog_size: size, + }, + }; + this.actionService.doAction(action); + } + + async openSmall() { + this.openDialog("small"); + } + + async openMedium() { + this.openDialog("medium"); + } + + async openLarge() { + this.openDialog("large"); + } + + async openExtraLarge() { + this.openDialog("extra-large"); + } + + async openFullscreen() { + this.openDialog("fullscreen"); + } +} + +registry.category("actions").add("issue.version", Version); diff --git a/issue/static/src/version.xml b/issue/static/src/version.xml new file mode 100644 index 000000000..3c4a34a5c --- /dev/null +++ b/issue/static/src/version.xml @@ -0,0 +1,13 @@ + + + +

Hello Dialog

+
+ + + + + +
+
+
\ No newline at end of file diff --git a/issue/views/issue_ticket_menus.xml b/issue/views/issue_ticket_menus.xml new file mode 100644 index 000000000..04ec524bd --- /dev/null +++ b/issue/views/issue_ticket_menus.xml @@ -0,0 +1,21 @@ + + /> + + 所有问题 + issue.ticket + tree,form + + + + + Version Control + issue.version + + + \ No newline at end of file diff --git a/issue/views/issue_ticket_views.xml b/issue/views/issue_ticket_views.xml new file mode 100644 index 000000000..32f36b6e4 --- /dev/null +++ b/issue/views/issue_ticket_views.xml @@ -0,0 +1,94 @@ + + + 问题单表单视图 + issue.ticket + +
+
+ + + + + + + +
+ +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + 问题单列表视图 + issue.ticket + + + + + + + + + + + + 问题单搜寻视图 + issue.ticket + + + + + + + + + + + + + + + + + + 问题单 + issue.ticket + tree,form + + +

使用此模块创建与管理问题记录。

+
+
+
\ No newline at end of file