diff --git a/jikimo_frontend/__init__.py b/jikimo_frontend/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/jikimo_frontend/__manifest__.py b/jikimo_frontend/__manifest__.py
new file mode 100644
index 00000000..7c17b18a
--- /dev/null
+++ b/jikimo_frontend/__manifest__.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+{
+ 'name': '机企猫智能工厂 样式调整',
+ 'version': '1.0',
+ 'summary': '机企猫智能工厂 样式调整',
+ 'sequence': 1,
+ 'description': """
+在本模块,定义了样式的修改
+ """,
+ 'category': 'sf',
+ 'website': 'https://www.sf.jikimo.com',
+ 'depends': ['account', 'base', 'mrp_workorder', 'sale'],
+ 'data': [
+
+ ],
+ 'demo': [
+ ],
+ 'assets': {
+
+ 'web.assets_qweb': [
+ ],
+ 'web.assets_backend': [
+ 'jikimo_frontend/static/src/scss/test.scss',
+ ],
+
+ },
+ 'license': 'LGPL-3',
+ 'installable': True,
+ 'application': False,
+ 'auto_install': False,
+}
diff --git a/jikimo_frontend/static/src/scss/custom_style.scss b/jikimo_frontend/static/src/scss/custom_style.scss
new file mode 100644
index 00000000..a9f2cee8
--- /dev/null
+++ b/jikimo_frontend/static/src/scss/custom_style.scss
@@ -0,0 +1,151 @@
+.test_model {
+ display: flex !important;
+}
+
+.test_model > .o_form_label {
+ margin-left: 20px;
+ margin-right: 0px !important;
+ white-space: nowrap;
+}
+
+div:has(.o_required_modifier) > label::before {
+ content: '*' !important;
+ color: red !important;
+ padding: 0 4px !important;
+ vertical-align: top !important;
+ font-size: 1.5rem !important;
+}
+
+.my-image div {
+ width: 110px !important;
+ height: 110px !important;
+}
+
+.add_flex {
+ padding: 5px 0;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+}
+
+.maintenance_name {
+ font-weight: bold;
+}
+
+.o_kanban_renderer .o_kanban_record .o_kanban_record_has_image_fill .o_kanban_image_fill_left {
+ flex: unset !important;
+}
+
+.o_kanban_renderer .o_kanban_record .o_kanban_record_bottom {
+ margin-top: 5px;
+ display: inline !important;
+}
+
+td.o_required_modifier {
+ display: table-cell !important;
+}
+
+.show_state {
+ display: flex;
+ flex-direction: column;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 8px;
+ margin: auto;
+ height: 34px;
+}
+
+.show_state > div {
+ width: 12px;
+ height: 12px;
+ border: 1px solid #000
+}
+
+.show_state > div:nth-child(2) {
+ border-top: none;
+ border-bottom: none;
+}
+
+.oe_kanban_card.kanban_color_2 {
+ background-color: #FF4343 !important;
+ color: #fff;
+}
+
+.oe_kanban_card.kanban_color_1 {
+ background-color: #27FEA9 !important;
+ opacity: 0.7;
+ color: #fff;
+}
+
+.oe_kanban_card.kanban_color_3 {
+ background-color: rgb(255, 150, 0) !important;
+ color: #fff;
+}
+
+.my-image img {
+ width: 100%;
+ height: 100%;
+}
+
+.color_1 {
+ background-color: #27FEA9;
+}
+
+.color_2 {
+ background-color: #FF4343;
+}
+
+.color_3 {
+ background-color: rgb(255, 150, 0);
+}
+
+.font_color_1 {
+ color: rgb(0, 183, 0);
+}
+
+.font_color_2 {
+ color: #FF4343;
+}
+
+.font_color_3 {
+ color: rgb(255, 150, 0);
+}
+
+.o_kanban_card_header_title {
+ font-size: 15px;
+}
+
+.o_kanban_record_bottom {
+ font-family: '华文中宋';
+ //font-weight: bold;
+}
+
+.text-truncate {
+ overflow: unset !important;
+ text-overflow: unset !important;
+ white-space: unset !important;
+}
+
+.o_list_renderer .o_list_table tbody > tr > td:not(.o_list_record_selector):not(.o_handle_cell):not(.o_list_button):not(.o_list_record_remove) {
+ white-space: nowrap !important;
+}
+
+.o_status {
+ width: 18px;
+ height: 18px;
+}
+
+.czyg {
+ font-size: 12px;
+ margin-right: 10px;
+ color: #aaa;
+}
+
+.o_kanban_primary_left {
+ display: flex;
+ flex-direction: row-reverse;
+ justify-content: flex-start;
+}
+
+//-----------------------------------------------------------
\ No newline at end of file
diff --git a/sf_base/__manifest__.py b/sf_base/__manifest__.py
index 0640922a..5f4c6906 100644
--- a/sf_base/__manifest__.py
+++ b/sf_base/__manifest__.py
@@ -18,7 +18,7 @@
'views/common_view.xml',
'views/fixture_view.xml',
'views/functional_fixture_view.xml',
- # 'views/quick_easy_order_view.xml',
+ 'views/tool_other_features_view.xml',
'views/menu_view.xml',
"views/tool_views.xml",
"views/tool_menu.xml",
diff --git a/sf_base/models/__init__.py b/sf_base/models/__init__.py
index 20bf8c6b..93961162 100644
--- a/sf_base/models/__init__.py
+++ b/sf_base/models/__init__.py
@@ -3,7 +3,8 @@ from . import common
from . import tool_base_new
from . import fixture
from . import functional_fixture
-# from . import quick_easy_order
+from . import tool_other_features
+
diff --git a/sf_base/models/base.py b/sf_base/models/base.py
index 042b77f4..966ccdc5 100644
--- a/sf_base/models/base.py
+++ b/sf_base/models/base.py
@@ -35,7 +35,7 @@ class MachineBrand(models.Model):
code = fields.Char('编码')
name = fields.Char('名称')
tag_ids = fields.Many2many('sf.machine.brand.tags', 'rel_machine_brand_tags', string='类别')
- image_brand = fields.Image("品牌图片")
+ image_brand = fields.Image("图片")
remark = fields.Text('备注')
active = fields.Boolean('有效', default=True)
@@ -118,7 +118,7 @@ class MachineTool(models.Model):
supplier_id = fields.Many2one('res.partner', string='制造商',
domain="[('is_vendor', '=', True)]")
registration_date = fields.Date('注册日期')
- state_zc = fields.Selection([("已注册", "已注册"), ("未注册", "未注册")], string="注册状态", default='未注册', tracking=True)
+ state_zc = fields.Selection([("已注册", "已注册"), ("未注册", "未注册")], string="注册状态", default='未注册')
active = fields.Boolean('有效', default=True)
@api.constrains('rotate_speed')
@@ -279,7 +279,7 @@ class MachineToolType(models.Model):
feed_speed = fields.Char('进给速度(mm/min)')
tool_speed = fields.Char('刀具速度(m/min)')
distance_min = fields.Char('主轴端面至工作台面距离MIN(mm)')
- distance_max = fields.Char('主轴端面至工作台面距离MIN(mm)')
+ distance_max = fields.Char('主轴端面至工作台面距离MAX(mm)')
taper = fields.Char('主轴锥度(°)')
torque = fields.Char('主轴电机扭矩(n/m)')
motor_power = fields.Char('主轴电机功率(kw)')
diff --git a/sf_base/models/common.py b/sf_base/models/common.py
index 2e2cccf6..814dabb7 100644
--- a/sf_base/models/common.py
+++ b/sf_base/models/common.py
@@ -179,3 +179,9 @@ class MrsProductionProcessParameter(models.Model):
def get_gain_way(self, item):
process_parameter = self.env['sf.production.process.parameter'].search([('id', '=', item.id)])
return process_parameter
+
+ def _json_production_process_item_code(self, item):
+ code_arr = []
+ for i in item.parameter_ids:
+ code_arr.append(i.code)
+ return code_arr
diff --git a/sf_base/models/fixture.py b/sf_base/models/fixture.py
index 727f58bc..bc5b19f9 100644
--- a/sf_base/models/fixture.py
+++ b/sf_base/models/fixture.py
@@ -26,7 +26,6 @@ class FixtureModel(models.Model):
_name = 'sf.fixture.model'
_description = "夹具型号"
- code = fields.Char(string='编码')
name = fields.Char(string="名称", size=15)
fixture_material_id = fields.Many2one('sf.fixture.material', string="夹具物料", )
fixture_material_type = fields.Char(string="夹具物料类型", related='fixture_material_id.name', store=True)
@@ -35,28 +34,58 @@ class FixtureModel(models.Model):
clamping_way = fields.Char(string="装夹方式")
port_type = fields.Char(string="接口类型")
model_file = fields.Binary(string="3D模型图")
- length = fields.Char(string="长度[mm]", size=6)
- width = fields.Char(string="宽度[mm]", size=6)
- height = fields.Char(string="高度[mm]", size=6)
- weight = fields.Char(string="重量[kg]", size=4)
- clamp_workpiece_length_max = fields.Integer(string="夹持工件长度MAX[mm]", size=6)
- clamp_workpiece_width_max = fields.Integer(string="夹持工件宽度MAX[mm]", size=6)
- clamp_workpiece_height_max = fields.Integer(string="夹持工件高度MAX[mm]", size=6)
- clamp_workpiece_diameter_max = fields.Float(string="夹持工件直径MAX[mm]", size=6)
- maximum_carrying_weight = fields.Float(string="最大承载重量[kg]", size=4)
- maximum_clamping_force = fields.Integer(string="最大夹持力[n]", size=8)
+
+ length = fields.Char(string="长度(mm)")
+ width = fields.Char(string="宽度(mm)")
+ height = fields.Char(string="高度(mm)")
+ weight = fields.Char(string="重量(kg)")
+ clamp_workpiece_length_max = fields.Integer(string="夹持工件长度max(mm)")
+ clamp_workpiece_width_max = fields.Integer(string="夹持工件宽度max(mm)")
+ clamp_workpiece_height_max = fields.Integer(string="夹持工件高度max(mm)")
+ clamp_workpiece_diameter_max = fields.Float(string="夹持工件直径max(mm)")
+ maximum_carrying_weight = fields.Float(string="最大承载重量(kg)")
+ maximum_clamping_force = fields.Integer(string="最大夹持力(n)")
+
materials_model_id = fields.Many2one('sf.materials.model', string="材料型号")
driving_way = fields.Selection([('气动', '气动'), ('液压', '液压'), ('机械', '机械')], string="驱动方式")
apply_machine_tool_type_ids = fields.Many2many('sf.machine_tool.type', 'rel_fixture_model_machine_tool_type',
string="适用机床型号")
- through_hole_size = fields.Integer(string="过孔大小[mm]", size=6)
- screw_size = fields.Integer(string="螺牙大小[mm]", size=6)
+ through_hole_size = fields.Integer(string="过孔大小[mm]")
+ screw_size = fields.Integer(string="螺牙大小[mm]")
active = fields.Boolean('有效', default=True)
- # @api.model
- # def create(self, vals):
- # obj = super(FixtureModel, self).create(vals)
- # return obj
+ def _get_code(self, fixture_model_type_code):
+ fixture_model = self.env['sf.fixture.model'].sudo().search(
+ [('code', 'ilike', fixture_model_type_code)],
+ limit=1,
+ order="id desc")
+ if not fixture_model:
+ num = "%03d" % 1
+ else:
+ m = int(fixture_model.code[-3:]) + 1
+ num = "%03d" % m
+ return "%s%s" % (fixture_model_type_code, num)
+ code = fields.Char(string='编码', readonly=True)
+ def _onchange_fixture_material_id(self, fixture_material_id):
+ if fixture_material_id:
+ if fixture_material_id.name == "气动夹具":
+ code = self._get_code("JKM-C-JJWL-QDJJ-")
+ elif fixture_material_id.name == "转接板(锁板)夹具":
+ code = self._get_code("JKM-C-JJWL-ZJBJJ-")
+ elif fixture_material_id.name == "磁吸夹具":
+ code = self._get_code("JKM-C-JJWL-CXJJ-")
+ elif fixture_material_id.name == "虎钳夹具":
+ code = self._get_code("JKM-C-JJWL-HQJJ-")
+ else:
+ code = self._get_code("JKM-C-JJWL-LDKP-")
+ return code
+ @api.model_create_multi
+ def create(self, vals):
+ obj = super(FixtureModel, self).create(vals)
+ if obj.fixture_material_id:
+ code = self._onchange_fixture_material_id(obj.fixture_material_id)
+ obj.code = code
+ return obj
diff --git a/sf_base/models/functional_fixture.py b/sf_base/models/functional_fixture.py
index 5a769757..c96466c1 100644
--- a/sf_base/models/functional_fixture.py
+++ b/sf_base/models/functional_fixture.py
@@ -36,7 +36,7 @@ class FunctionalFixture(models.Model):
domain=[('fixture_material_type', '=', '磁吸托盘')])
vice_tray_model_ids = fields.Many2many('sf.fixture.model', 'rel_fixture_model_vice_tray', string="虎钳托盘型号",
domain=[('fixture_material_type', '=', '虎钳托盘')])
- registration_status = fields.Selection([("已注册", "已注册"), ("未注册", "未注册")], string="注册状态", default='未注册', tracking=True)
+ registration_status = fields.Selection([("已注册", "已注册"), ("未注册", "未注册")], string="注册状态", default='未注册')
active = fields.Boolean('有效', default=True)
@api.onchange('type_id')
diff --git a/sf_base/models/quick_easy_order.py b/sf_base/models/quick_easy_order.py
deleted file mode 100644
index c39b3fc5..00000000
--- a/sf_base/models/quick_easy_order.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from odoo import models, fields
-import datetime
-import base64
-
-
-class QuickEasyOrder(models.Model):
- _name = 'quick.easy.order'
- _description = '简易下单'
-
- name = fields.Char('订单编号', default=lambda self: self.env['ir.sequence'].next_by_code('quick.easy.order'))
- machining_precision = fields.Selection([
- ('0.10', '±0.10mm'),
- ('0.05', '±0.05mm'),
- ('0.03', '±0.03mm'),
- ('0.02', '±0.02mm'),
- ('0.01', '±0.01mm')], string='加工精度')
- material_id = fields.Many2one('sf.production.materials', '材料')
- material_model_id = fields.Many2one('sf.materials.model', '型号')
- process_id = fields.Many2one('sf.production.process', string='表面工艺')
- parameter_ids = fields.One2many('sf.production.process.parameter', 'process_id', string='可选参数')
- quantity = fields.Integer('数量')
- price = fields.Float('总价')
- model_file = fields.Binary('模型文件')
- upload_model_file = fields.Many2many('ir.attachment', 'upload_qf_model_file_attachment_ref', string='上传模型文件')
- delivery_time = fields.Date('交货日期')
- customer_id = fields.Many2one('res.partner', string='客户', default=lambda self: self.env.user.partner_id.id)
diff --git a/sf_base/models/tool_base_new.py b/sf_base/models/tool_base_new.py
index 575afd5f..fc62074e 100644
--- a/sf_base/models/tool_base_new.py
+++ b/sf_base/models/tool_base_new.py
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
from odoo import fields, models, api
+
+
# from datetime import datetime
# from odoo.exceptions import ValidationError
@@ -95,18 +97,18 @@ class CuttingToolModel(models.Model):
_description = '刀具型号'
name = fields.Char('名称')
- code = fields.Char('编码')
cutting_tool_material_id = fields.Many2one('sf.cutting.tool.material', string='刀具物料')
cutting_tool_type = fields.Char(string="刀具物料类型", related='cutting_tool_material_id.name', store=True)
cutting_tool_type_id = fields.Many2one('sf.cutting.tool.type', string='刀具类型',
)
brand_id = fields.Many2one('sf.machine.brand', '品牌')
- tool_length = fields.Integer('长度(mm)', size=6)
- tool_width = fields.Integer('宽度(mm)', size=6)
- tool_height = fields.Integer('高度(mm)', size=6)
- tool_thickness = fields.Integer('厚度(mm)', size=6)
- tool_weight = fields.Float('重量(kg)', size=4)
+ tool_length = fields.Integer('长度(mm)')
+ tool_width = fields.Integer('宽度(mm)')
+ tool_height = fields.Integer('高度(mm)')
+ tool_thickness = fields.Integer('厚度(mm)')
+ tool_weight = fields.Float('重量(kg)')
coating_material = fields.Char('涂层材质')
+
# 整体式刀具参数
total_length = fields.Float('总长度(mm)')
shank_length = fields.Float('柄部长度(mm)')
@@ -177,12 +179,43 @@ class CuttingToolModel(models.Model):
)
active = fields.Boolean('有效', default=True)
- # @api.model
- # def create(self, vals):
- # if vals.get('name', '/') == '/' or vals.get('name', '/') is False:
- # vals['name'] = '/'
- # obj = super(CuttingToolModel, self).create(vals)
- # return obj
+ def _get_code(self, cutting_tool_type_code):
+ cutting_tool_model = self.search(
+ [('code', 'ilike', cutting_tool_type_code)],
+ limit=1,
+ order="id desc")
+ if not cutting_tool_model:
+ num = "%03d" % 1
+ else:
+ m = int(cutting_tool_model.code[-3:]) + 1
+ num = "%03d" % m
+ return "%s%s" % (cutting_tool_type_code, num)
+
+ code = fields.Char(string='编码', readonly=True)
+
+ def _onchange_cutting_tool_material_id(self, cutting_tool_material_id):
+ if cutting_tool_material_id:
+ if cutting_tool_material_id.name == "整体式刀具":
+ code = self._get_code("JKM-T-DJWL-ZTDJ-")
+ elif cutting_tool_material_id.name == "刀片":
+ code = self._get_code("JKM-T-DJWL-DPIA-")
+ elif cutting_tool_material_id.name == "刀杆":
+ code = self._get_code("JKM-T-DJWL-DGAN-")
+ elif cutting_tool_material_id.name == "刀盘":
+ code = self._get_code("JKM-T-DJWL-DPAN-")
+ elif cutting_tool_material_id.name == "夹头":
+ code = self._get_code("JKM-T-DJWL-DJIA-")
+ else:
+ code = self._get_code("JKM-T-DJWL-DBIN-")
+ return code
+
+ @api.model_create_multi
+ def create(self, vals):
+ obj = super(CuttingToolModel, self).create(vals)
+ if obj.cutting_tool_material_id:
+ code = self._onchange_cutting_tool_material_id(obj.cutting_tool_material_id)
+ obj.code = code
+ return obj
# 刀具类型
diff --git a/sf_base/models/tool_other_features.py b/sf_base/models/tool_other_features.py
new file mode 100644
index 00000000..129b0199
--- /dev/null
+++ b/sf_base/models/tool_other_features.py
@@ -0,0 +1,73 @@
+from odoo import fields, models
+
+
+class SuitableMachiningMethod(models.Model):
+ _name = 'sf.suitable.machining.method'
+ _description = '适合加工方式'
+
+ name = fields.Char('名称')
+ image = fields.Image('图片')
+
+
+class BladeTipCharacteristics(models.Model):
+ _name = 'sf.blade.tip.characteristics'
+ _description = '刀尖特征'
+
+ name = fields.Char('名称')
+ image = fields.Image('图片')
+
+
+class HandleType(models.Model):
+ _name = 'sf.handle.type'
+ _description = '柄部类型'
+
+ name = fields.Char('名称')
+ image = fields.Image('图片')
+
+
+class CuttingDirection(models.Model):
+ _name = 'sf.cutting.direction'
+ _description = '走刀方向'
+
+ name = fields.Char('名称')
+ image = fields.Image('图片')
+
+
+class SuitableCoolant(models.Model):
+ _name = 'sf.suitable.coolant'
+ _description = '适合冷却液'
+
+ name = fields.Char('名称')
+ image = fields.Image('图片')
+
+
+class CuttingSpeed(models.Model):
+ _name = 'sf.cutting.speed'
+ _description = '切削速度Vc'
+
+ # def _get_order(self):
+ # last_tool = self.search([], order='id desc', limit=1)
+ # if last_tool:
+ # last_order = int(last_tool.order)
+ # new_order = last_order + 1
+ # else:
+ # new_order = '1'
+ # return new_order
+ #
+ # order = fields.Char('序', default=_get_order, readonly=True)
+
+ execution_standard_id = fields.Char('执行标准')
+ material_code = fields.Char('材料代号')
+ material_name = fields.Char('材料名称')
+ material_grade = fields.Char('材料牌号')
+ tensile_strength = fields.Char('拉伸强度 (N/mm²)')
+ hardness = fields.Char('硬度(HRC)')
+
+ cutting_speed_n1 = fields.Char('径向切宽 ae=100%D1 ap=1*D1 切削速度Vc')
+ cutting_speed_n2 = fields.Char('径向切宽 ae=50%D1 ap=1.5*D1 切削速度Vc')
+ cutting_speed_n3 = fields.Char('径向切宽 ae=25%D1 ap=L1max 切削速度Vc')
+ cutting_speed_n4 = fields.Char('径向切宽 ae=15%D1 ap=L1max 切削速度Vc')
+ cutting_speed_n5 = fields.Char('径向切宽 ae=5%D1 ap=L1max 切削速度Vc')
+ rough_machining = fields.Char('粗加工 Vc(m/min)')
+ precision_machining = fields.Char('精加工 Vc(m/min)')
+ application = fields.Selection([('主应用', '主应用'), ('次应用', '次应用')], '主/次应用')
\ No newline at end of file
diff --git a/sf_base/security/ir.model.access.csv b/sf_base/security/ir.model.access.csv
index 03e2a81b..73661ae8 100644
--- a/sf_base/security/ir.model.access.csv
+++ b/sf_base/security/ir.model.access.csv
@@ -23,6 +23,13 @@ access_sf_multi_mounting_type,sf_multi_mounting_type,model_sf_multi_mounting_typ
access_sf_fixture_model,sf_fixture_model,model_sf_fixture_model,base.group_user,1,1,1,1
access_sf_functional_fixture_type,sf_functional_fixture_type,model_sf_functional_fixture_type,base.group_user,1,1,1,1
access_sf_functional_fixture,sf_functional_fixture,model_sf_functional_fixture,base.group_user,1,1,1,1
+access_sf_sync_common,sf_sync_common,model_sf_sync_common,base.group_user,1,1,1,1
+access_sf_suitable_machining_method,sf_suitable_machining_method,model_sf_suitable_machining_method,base.group_user,1,1,1,1
+access_sf_blade_tip_characteristics,sf_blade_tip_characteristics,model_sf_blade_tip_characteristics,base.group_user,1,1,1,1
+access_sf_handle_type,sf_handle_type,model_sf_handle_type,base.group_user,1,1,1,1
+access_sf_cutting_direction,sf_cutting_direction,model_sf_cutting_direction,base.group_user,1,1,1,1
+access_sf_suitable_coolant,sf_suitable_coolant,model_sf_suitable_coolant,base.group_user,1,1,1,1
+access_sf_cutting_speed,sf_cutting_speed,model_sf_cutting_speed,base.group_user,1,1,1,1
diff --git a/sf_base/static/src/scss/test.scss b/sf_base/static/src/scss/test.scss
index faef4815..39c5250f 100644
--- a/sf_base/static/src/scss/test.scss
+++ b/sf_base/static/src/scss/test.scss
@@ -119,4 +119,31 @@ td.o_required_modifier {
.o_kanban_record_bottom {
font-family: '华文中宋';
//font-weight: bold;
+}
+
+.text-truncate {
+ overflow: unset !important;
+ text-overflow: unset !important;
+ white-space: unset !important;
+}
+
+.o_list_renderer .o_list_table tbody > tr > td:not(.o_list_record_selector):not(.o_handle_cell):not(.o_list_button):not(.o_list_record_remove) {
+ white-space: nowrap !important;
+}
+
+.o_status {
+ width: 18px;
+ height: 18px;
+}
+
+.czyg {
+ font-size: 12px;
+ margin-right: 10px;
+ color: #aaa;
+}
+
+.o_kanban_primary_left {
+ display: flex;
+ flex-direction: row-reverse;
+ justify-content: flex-start;
}
\ No newline at end of file
diff --git a/sf_base/views/base_view.xml b/sf_base/views/base_view.xml
index cdff5a4b..8c8e1632 100644
--- a/sf_base/views/base_view.xml
+++ b/sf_base/views/base_view.xml
@@ -29,8 +29,8 @@
- 添加维保计划 + 添加维保计划
跟进请求的处理,并且和合作者沟通。
@@ -66,5 +69,32 @@