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 000000000..9c50d2825 Binary files /dev/null and b/issue/static/description/icon.png differ diff --git a/issue/static/description/icon.svg b/issue/static/description/icon.svg new file mode 100644 index 000000000..925e18dfb --- /dev/null +++ b/issue/static/description/icon.svg @@ -0,0 +1,6 @@ + + + + + + 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