• 首页
  • 产品中心
    • 数式Oinone四大产品

      低代码开发平台无代码开发平台集成开发平台AI大模型开发
    • 数式Oinone体系能力

      用户与组织权限管理文件管理消息中心国际化业务审计
    • 数式Oinone核心产品特性

      低无一体面向软件公司场景无限制应用级扩容可分可合
  • 服务中心
    • 客户服务

      预约演示方案咨询私有部署找人定制
    • 开发者

      问答下载
    • Oinone学院

      社区学习

    《精讲面向软件公司的低代码平台——以Oinone为例》

  • 合作伙伴
    渠道申请伙伴名录专家库
  • 关于数式
0571-88757863

Coding Guidelines


This article introduces the Oinone Coding Guidelines. These guidelines aim to improve the quality of Oinone application code. In fact, proper code can enhance readability, simplify maintenance, facilitate debugging, reduce complexity, and improve reliability.

1. Module Design

Refer to: Modular Design

2. Model Design

Refer to: Model Design

3. Naming Conventions

(I) Frontend

1. Vue Files

For relevant specifications of Vue files, refer to: Vue Style Guide

2. TypeScript Files

2.1 Naming Conventions

File names use PascalCase, and the file name should be consistent with the class name. Taking custom fields as an example: the file name and class name are composed of ${ViewType}${FieldType}${Component Type}${FieldWidget}, such as FormM2OSelectFieldWidget.ts.

2.2 Inheritance

Class names use PascalCase. When inheriting, inherit the default widget. Taking a custom m2o dropdown field as an example:

export class FormM2ODialogFieldWidget extends FormM2OSelectFieldWidget{
  // ...todo
}

2.3 Method Definition

Define different modifiers (public, protected, private) according to the role of the method, and method names use camelCase. If it is a responsive method, it needs to be marked with the @Widget.Method() decorator.

@Widget.Method()
public change(value: string):{}

2.4 Property Definition

Define different modifiers (public, protected, private) according to the role of the property, and property names use camelCase. If it is a responsive property, it needs to be marked with the @Widget.Reactive() decorator. For computed properties, the corresponding get accessor should be added.

@Widget.Reactive()
public get userInfo() {
  return `Age: ${this.age}, Name: ${this.myName}`
}

@Widget.Reactive()
public myName = 'Zhang San'

@Widget.Reactive()
public age = 18

(II) Backend

1. Class Names

For platform model naming conventions, refer to: Model Naming Conventions. Ordinary POJO class names use PascalCase.

2. Property Names

For platform model field naming conventions, refer to: Model Fields. Ordinary POJO property names use camelCase.

3. Method Names

Method names use camelCase. If the method is a Function or Action, avoid using get, set, or unset as the method name prefix.

4. Notes

(I) Frontend

1. Cohesion of Methods and Properties in Corresponding Classes

Whether it is a custom field, action, or view, its properties and methods should be written in the corresponding class. Vue components are only responsible for accepting corresponding properties and methods through props and do not handle business logic. Because class can be inherited, and its properties and methods can be overridden, which enables universality.

// FormM2ODialog.vue
<script  lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
  name: 'test',
  props: {
    userInfo: {
      type: Object,
      default: () => ({})
    },
    changeUserInfo: {
      type: Function,
      default: () => {}
    }
  }
})
</script>

// FormM2ODialogWidget.ts
@SPI.ClassFactory(
  FormFieldWidget.Token({
    ...
  })
)
export class FormM2ODialogWidget extends FormM2OSelectFieldWidget {
  public initialize(props) {
    super.initialize(props);
    this.setComponent(FormM2ODialog);
    return this;
  }

  @Widget.Reactive()
  public get userInfo() {
    return `Age: ${this.age}, Name: ${this.myName}`
  }
  
  @Widget.Reactive()
  public myName = 'Zhang San'
  
  @Widget.Reactive()
  public age = 18

  
  @Widget.Method()
  public changeUserInfo(age: number){
    this.age = age
  }
}

2. Import and Export of Files

Classes in TypeScript files use export. Folders of different types need to have an index.ts file to unify the import and export of files.

├── field
├──── form
├────── string // Fields related to string type
├──────── input
├──────── select
├──────── index.ts // Export input and select
├────── index.ts // Export string
└── index.ts // Only export form

3. Debugging Tools

Use the latest version of Vue Devtools as the component debugging tool.

(II) Backend

1. Deep Copy

Use the cloning tool provided by the platform: pro.shushi.pamirs.framework.common.utils.ObjectUtils#clone

2. JSON Serialization/Deserialization

Use the Json operation tool provided by the platform: pro.shushi.pamirs.meta.util.JsonUtils

3. Getter/Setter

The underlying model uses Map as the data carrier. When manually overriding Getter and Setter methods, property reading and writing must be implemented by operating this Map.

The following code example shows manually writing Getter, Setter, and UnSetter:

@Model(displayName = "TestA")
@Model.model("test.TestA")
public class TestA extends IdModel {

    private static final long serialVersionUID = 2306247193831238288L;

    public static final String MODEL_MODEL = "test.TestA";

    @Field(displayName = "Name")
    @Field.String
    private String name;
    
    public String getName() {
        return (String)this._d.get("name");
    }

    public TestA setName(String name) {
        this._d.put("name", name);
        return this;
    }

    public TestA unsetName() {
        this._d.remove("name");
        return this;
    }
}

5. Code Format

(I) Frontend

Frontend code is formatted with prettier.

Configuration file reference:

Configuration file name: .prettierrc.json

{
  "tabWidth": 2,
  "printWidth": 120,
  "singleQuote": true,
  "semi": true,
  "trailingComma": "none",
  "arrowParens": "always"
}

(II) Backend

Backend code format is based on IDEA's default package import and formatting.

6. Code Comments

Clear and accurate code comments with logical descriptions are advocated.

Edit this page
Last Updated:1/15/26, 4:02 AM
Prev
Git Guidelines
Next
Content Guidelines
默认页脚
Copyright © 2026 Mr.Hope