Commit 6d596a9c authored by WangXu's avatar WangXu

完善 中汽规范文档 文件命名

按照规范修改 任务模板设计
parent 7000c312
...@@ -22,3 +22,33 @@ ...@@ -22,3 +22,33 @@
### 示例 ### 示例
![文件命名示例](./doc/文件命名示例图片.png) ![文件命名示例](./doc/文件命名示例图片.png)
## HTML编写规范
### 规则
1. 使用常用且熟悉的语义类标签,不能确定使用哪个就用 `div``span`
如: `<ul>/<ol> > <li> `, `<h1> - <h6>`, `<pre>`, `<a>`, `<button>`, `<input>`
**对于语义标签,我的态度是:
“用对”比“不用”好,“不用”比“,“不用”比“用错”好。
当然了,我觉得有理想的前端工程师还是应该去追求“用对”它们。**
[W3C标签列表参考](http://www.w3school.com.cn/tags/index.asp)
[MDN标签列表参考](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element)
2. 显式指明使用到的属性,且属性值一定要有值并且用 `""`。如: `<button type="button">按钮</button>`
3. 省略结束标签请遵循 [MDN的HTML元素参考](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element)
| 标签省略 | HTML元素举例 |
|:----:|:---:|
| 必须有一个开始标签,不允许有结束标签. | `<img src="./xx.png"/>` |
| 不允许,开始标签和结束标签都不能省略。 | `<a></a>` |
| 必须有开始标签但不必有结束标签。| `<input size="32"/>` `<input size="32"></input>`|
**结束标签不存在时,在开始标签后加 `/`**
4. 给每个 `<table>``<form>` 加上唯一的 id
5. 给每个 `<img>` 加上 alt 属性
## CSS 编写规范
...@@ -14,7 +14,7 @@ export const asyncRouterMap = [ ...@@ -14,7 +14,7 @@ export const asyncRouterMap = [
{ {
path: '/taskGrouping', path: '/taskGrouping',
name: 'taskGrouping', name: 'taskGrouping',
component: () => import('@/views/taskTemplate/taskGrouping/index.vue'), component: () => import('@/views/taskTemplate/taskGrouping'),
meta: { title: '任务分组', keepAlive: true, permission: ['taskGrouping'] } meta: { title: '任务分组', keepAlive: true, permission: ['taskGrouping'] }
}, },
{ {
...@@ -28,25 +28,25 @@ export const asyncRouterMap = [ ...@@ -28,25 +28,25 @@ export const asyncRouterMap = [
{ {
path: '/taskSetting', path: '/taskSetting',
name: 'taskSetting', name: 'taskSetting',
component: () => import('@/views/taskTemplate/taskSetting'), component: () => import('@/views/taskTemplate/taskDesign/taskSetting'),
meta: { title: '任务基础设置', keepAlive: true, permission: ['taskSetting'] } meta: { title: '任务基础设置', keepAlive: true, permission: ['taskSetting'] }
}, },
{ {
path: '/taskFlow', path: '/taskFlow',
name: 'taskFlow', name: 'taskFlow',
component: () => import('@/views/taskTemplate/taskFlow'), component: () => import('@/views/taskTemplate/taskDesign/taskFlow'),
meta: { title: '任务流程', keepAlive: true, permission: ['taskFlow'] } meta: { title: '任务流程', keepAlive: true, permission: ['taskFlow'] }
}, },
{ {
path: '/taskNewForm', path: '/taskNewForm',
name: 'taskNewForm', name: 'taskNewForm',
component: () => import('@/views/taskTemplate/taskNewForm/index'), component: () => import('@/views/taskTemplate/taskDesign/taskNewForm'),
meta: { title: '任务面板编辑', keepAlive: true } meta: { title: '任务面板编辑', keepAlive: true }
}, },
{ {
path: '/taskOtherSetting', path: '/taskOtherSetting',
name: 'taskOtherSetting', name: 'taskOtherSetting',
component: () => import('@/views/taskTemplate/taskOtherSetting'), component: () => import('@/views/taskTemplate/taskDesign/taskOtherSetting'),
meta: { title: '任务其他设置', keepAlive: true, permission: ['taskOtherSetting'] } meta: { title: '任务其他设置', keepAlive: true, permission: ['taskOtherSetting'] }
}, },
{ {
......
# 文件夹说明
此文件夹是 `新建模板` 的四个页面的相关内容
# 文件夹说明
此文件夹是 `任务流程设置页面` 相关内容
export default class CustomContextPad {
constructor(config, contextPad, create, elementFactory, injector, translate) {
this.create = create;
this.elementFactory = elementFactory;
this.translate = translate;
if (config.autoPlace !== false) {
this.autoPlace = injector.get('autoPlace', false);
}
contextPad.registerProvider(this);
}
getContextPadEntries(element) {
const {
autoPlace,
create,
elementFactory,
translate
} = this;
function appendServiceTask(event, element) {
if (autoPlace) {
const shape = elementFactory.createShape({ type: 'bpmn:ServiceTask' });
autoPlace.append(element, shape);
} else {
appendServiceTaskStart(event, element);
}
}
function appendServiceTaskStart(event) {
const shape = elementFactory.createShape({ type: 'bpmn:ServiceTask' });
create.start(event, shape, element);
}
return {
'append.service-task': {
group: 'model',
className: 'bpmn-icon-service-task',
title: translate('Append ServiceTask'),
action: {
click: appendServiceTask,
dragstart: appendServiceTaskStart
}
}
};
}
}
CustomContextPad.$inject = [
'config',
'contextPad',
'create',
'elementFactory',
'injector',
'translate'
];
export default class CustomPalette {
constructor(create, elementFactory, palette, translate) {
this.create = create;
this.elementFactory = elementFactory;
this.translate = translate;
palette.registerProvider(this);
}
getPaletteEntries(element) {
const {
create,
elementFactory,
translate
} = this;
function createServiceTask(event) {
const shape = elementFactory.createShape({ type: 'bpmn:ServiceTask' });
create.start(event, shape);
}
function createUserTask(event) {
const shape = elementFactory.createShape({ type: 'bpmn:UserTask' });
create.start(event, shape);
}
return {
'create.service-task': {
group: 'activity',
className: 'bpmn-icon-service-task',
title: translate('Create {type}', { type: 'Service Task' }),
action: {
dragstart: createServiceTask,
click: createServiceTask
}
},
'create.user-task': {
group: 'activity',
className: 'bpmn-icon-user-task',
title: translate('Create {type}', { type: 'User Task' }),
action: {
dragstart: createUserTask,
click: createUserTask
}
}
};
}
}
CustomPalette.$inject = [
'create',
'elementFactory',
'palette',
'translate'
];
import CustomContextPad from './CustomContextPad';
import CustomPalette from './CustomPalette';
export default {
__init__: [ 'customContextPad', 'customPalette' ],
customContextPad: [ 'type', CustomContextPad ],
customPalette: [ 'type', CustomPalette ]
};
\ No newline at end of file
import {
getBusinessObject,
is
} from 'bpmn-js/lib/util/ModelUtil';
import {
isEventSubProcess,
isExpanded
} from 'bpmn-js/lib/util/DiUtil';
import {
isDifferentType
} from './util/TypeUtil';
import {
forEach,
filter
} from 'min-dash';
import * as replaceOptions from './ReplaceOptions';
/**
* This module is an element agnostic replace menu provider for the popup menu.
*/
export default function ReplaceMenuProvider(
popupMenu, modeling, moddle,
bpmnReplace, rules, translate) {
this._popupMenu = popupMenu;
this._modeling = modeling;
this._moddle = moddle;
this._bpmnReplace = bpmnReplace;
this._rules = rules;
this._translate = translate;
this.register();
}
ReplaceMenuProvider.$inject = [
'popupMenu',
'modeling',
'moddle',
'bpmnReplace',
'rules',
'translate'
];
/**
* Register replace menu provider in the popup menu
*/
ReplaceMenuProvider.prototype.register = function() {
this._popupMenu.registerProvider('bpmn-replace', this);
};
/**
* Get all entries from replaceOptions for the given element and apply filters
* on them. Get for example only elements, which are different from the current one.
*
* @param {djs.model.Base} element
*
* @return {Array<Object>} a list of menu entry items
*/
ReplaceMenuProvider.prototype.getEntries = function(element) {
var businessObject = element.businessObject;
var rules = this._rules;
var entries;
if (!rules.allowed('shape.replace', { element: element })) {
return [];
}
var differentType = isDifferentType(element);
// start events outside event sub processes
if (is(businessObject, 'bpmn:StartEvent') && !isEventSubProcess(businessObject.$parent)) {
entries = filter(replaceOptions.START_EVENT, differentType);
return this._createEntries(element, entries);
}
// expanded/collapsed pools
if (is(businessObject, 'bpmn:Participant')) {
entries = filter(replaceOptions.PARTICIPANT, function(entry) {
return isExpanded(businessObject) !== entry.target.isExpanded;
});
return this._createEntries(element, entries);
}
// start events inside event sub processes
if (is(businessObject, 'bpmn:StartEvent') && isEventSubProcess(businessObject.$parent)) {
entries = filter(replaceOptions.EVENT_SUB_PROCESS_START_EVENT, function(entry) {
var target = entry.target;
var isInterrupting = target.isInterrupting !== false;
var isInterruptingEqual = getBusinessObject(element).isInterrupting === isInterrupting;
// filters elements which types and event definition are equal but have have different interrupting types
return differentType(entry) || !differentType(entry) && !isInterruptingEqual;
});
return this._createEntries(element, entries);
}
// end events
if (is(businessObject, 'bpmn:EndEvent')) {
entries = filter(replaceOptions.END_EVENT, function(entry) {
var target = entry.target;
// hide cancel end events outside transactions
if (target.eventDefinitionType == 'bpmn:CancelEventDefinition' && !is(businessObject.$parent, 'bpmn:Transaction')) {
return false;
}
return differentType(entry);
});
return this._createEntries(element, entries);
}
// boundary events
if (is(businessObject, 'bpmn:BoundaryEvent')) {
entries = filter(replaceOptions.BOUNDARY_EVENT, function(entry) {
var target = entry.target;
if (target.eventDefinition == 'bpmn:CancelEventDefinition' &&
!is(businessObject.attachedToRef, 'bpmn:Transaction')) {
return false;
}
var cancelActivity = target.cancelActivity !== false;
var isCancelActivityEqual = businessObject.cancelActivity == cancelActivity;
return differentType(entry) || !differentType(entry) && !isCancelActivityEqual;
});
return this._createEntries(element, entries);
}
// intermediate events
if (is(businessObject, 'bpmn:IntermediateCatchEvent') ||
is(businessObject, 'bpmn:IntermediateThrowEvent')) {
entries = filter(replaceOptions.INTERMEDIATE_EVENT, differentType);
return this._createEntries(element, entries);
}
// gateways
if (is(businessObject, 'bpmn:Gateway')) {
entries = filter(replaceOptions.GATEWAY, differentType);
return this._createEntries(element, entries);
}
// transactions
if (is(businessObject, 'bpmn:Transaction')) {
entries = filter(replaceOptions.TRANSACTION, differentType);
return this._createEntries(element, entries);
}
// expanded event sub processes
if (isEventSubProcess(businessObject) && isExpanded(businessObject)) {
entries = filter(replaceOptions.EVENT_SUB_PROCESS, differentType);
return this._createEntries(element, entries);
}
// expanded sub processes
if (is(businessObject, 'bpmn:SubProcess') && isExpanded(businessObject)) {
entries = filter(replaceOptions.SUBPROCESS_EXPANDED, differentType);
return this._createEntries(element, entries);
}
// collapsed ad hoc sub processes
if (is(businessObject, 'bpmn:AdHocSubProcess') && !isExpanded(businessObject)) {
entries = filter(replaceOptions.TASK, function(entry) {
var target = entry.target;
var isTargetSubProcess = target.type === 'bpmn:SubProcess';
var isTargetExpanded = target.isExpanded === true;
return isDifferentType(element, target) && (!isTargetSubProcess || isTargetExpanded);
});
return this._createEntries(element, entries);
}
// sequence flows
if (is(businessObject, 'bpmn:SequenceFlow')) {
return this._createSequenceFlowEntries(element, replaceOptions.SEQUENCE_FLOW);
}
// flow nodes
if (is(businessObject, 'bpmn:FlowNode')) {
entries = filter(replaceOptions.TASK, differentType);
// collapsed SubProcess can not be replaced with itself
if (is(businessObject, 'bpmn:SubProcess') && !isExpanded(businessObject)) {
entries = filter(entries, function(entry) {
return entry.label !== 'Sub Process (collapsed)';
});
}
return this._createEntries(element, entries);
}
return [];
};
/**
* Get a list of header items for the given element. This includes buttons
* for multi instance markers and for the ad hoc marker.
*
* @param {djs.model.Base} element
*
* @return {Array<Object>} a list of menu entry items
*/
ReplaceMenuProvider.prototype.getHeaderEntries = function(element) {
var headerEntries = [];
if (is(element, 'bpmn:Activity') && !isEventSubProcess(element)) {
// headerEntries = headerEntries.concat(this._getLoopEntries(element));
}
if (is(element, 'bpmn:SubProcess') &&
!is(element, 'bpmn:Transaction') &&
!isEventSubProcess(element)) {
headerEntries.push(this._getAdHocEntry(element));
}
return headerEntries;
};
/**
* Creates an array of menu entry objects for a given element and filters the replaceOptions
* according to a filter function.
*
* @param {djs.model.Base} element
* @param {Object} replaceOptions
*
* @return {Array<Object>} a list of menu items
*/
ReplaceMenuProvider.prototype._createEntries = function(element, replaceOptions) {
var menuEntries = [];
var self = this;
forEach(replaceOptions, function(definition) {
var entry = self._createMenuEntry(definition, element);
menuEntries.push(entry);
});
return menuEntries;
};
/**
* Creates an array of menu entry objects for a given sequence flow.
*
* @param {djs.model.Base} element
* @param {Object} replaceOptions
* @return {Array<Object>} a list of menu items
*/
ReplaceMenuProvider.prototype._createSequenceFlowEntries = function(element, replaceOptions) {
var businessObject = getBusinessObject(element);
var menuEntries = [];
var modeling = this._modeling,
moddle = this._moddle;
var self = this;
forEach(replaceOptions, function(entry) {
switch (entry.actionName) {
case 'replace-with-default-flow':
if (businessObject.sourceRef.default !== businessObject &&
(is(businessObject.sourceRef, 'bpmn:ExclusiveGateway') ||
is(businessObject.sourceRef, 'bpmn:InclusiveGateway') ||
is(businessObject.sourceRef, 'bpmn:ComplexGateway') ||
is(businessObject.sourceRef, 'bpmn:Activity'))) {
menuEntries.push(self._createMenuEntry(entry, element, function() {
modeling.updateProperties(element.source, { default: businessObject });
}));
}
break;
case 'replace-with-conditional-flow':
if (!businessObject.conditionExpression && is(businessObject.sourceRef, 'bpmn:Activity')) {
menuEntries.push(self._createMenuEntry(entry, element, function() {
var conditionExpression = moddle.create('bpmn:FormalExpression', { body: '' });
modeling.updateProperties(element, { conditionExpression: conditionExpression });
}));
}
break;
default:
// default flows
if (is(businessObject.sourceRef, 'bpmn:Activity') && businessObject.conditionExpression) {
return menuEntries.push(self._createMenuEntry(entry, element, function() {
modeling.updateProperties(element, { conditionExpression: undefined });
}));
}
// conditional flows
if ((is(businessObject.sourceRef, 'bpmn:ExclusiveGateway') ||
is(businessObject.sourceRef, 'bpmn:InclusiveGateway') ||
is(businessObject.sourceRef, 'bpmn:ComplexGateway') ||
is(businessObject.sourceRef, 'bpmn:Activity')) &&
businessObject.sourceRef.default === businessObject) {
return menuEntries.push(self._createMenuEntry(entry, element, function() {
modeling.updateProperties(element.source, { default: undefined });
}));
}
}
});
return menuEntries;
};
/**
* Creates and returns a single menu entry item.
*
* @param {Object} definition a single replace options definition object
* @param {djs.model.Base} element
* @param {Function} [action] an action callback function which gets called when
* the menu entry is being triggered.
*
* @return {Object} menu entry item
*/
ReplaceMenuProvider.prototype._createMenuEntry = function(definition, element, action) {
var translate = this._translate;
var replaceElement = this._bpmnReplace.replaceElement;
var replaceAction = function() {
return replaceElement(element, definition.target);
};
action = action || replaceAction;
var menuEntry = {
label: translate(definition.label),
className: definition.className,
id: definition.actionName,
action: action
};
return menuEntry;
};
/**
* Get a list of menu items containing buttons for multi instance markers
*
* @param {djs.model.Base} element
*
* @return {Array<Object>} a list of menu items
*/
ReplaceMenuProvider.prototype._getLoopEntries = function(element) {
var self = this;
var translate = this._translate;
function toggleLoopEntry(event, entry) {
var loopCharacteristics;
if (entry.active) {
loopCharacteristics = undefined;
} else {
loopCharacteristics = self._moddle.create(entry.options.loopCharacteristics);
if (entry.options.isSequential) {
loopCharacteristics.isSequential = entry.options.isSequential;
}
}
self._modeling.updateProperties(element, { loopCharacteristics: loopCharacteristics });
}
var businessObject = getBusinessObject(element),
loopCharacteristics = businessObject.loopCharacteristics;
var isSequential,
isLoop,
isParallel;
if (loopCharacteristics) {
isSequential = loopCharacteristics.isSequential;
isLoop = loopCharacteristics.isSequential === undefined;
isParallel = loopCharacteristics.isSequential !== undefined && !loopCharacteristics.isSequential;
}
var loopEntries = [
{
id: 'toggle-parallel-mi',
className: 'bpmn-icon-parallel-mi-marker',
title: translate('Parallel Multi Instance'),
active: isParallel,
action: toggleLoopEntry,
options: {
loopCharacteristics: 'bpmn:MultiInstanceLoopCharacteristics',
isSequential: false
}
},
{
id: 'toggle-sequential-mi',
className: 'bpmn-icon-sequential-mi-marker',
title: translate('Sequential Multi Instance'),
active: isSequential,
action: toggleLoopEntry,
options: {
loopCharacteristics: 'bpmn:MultiInstanceLoopCharacteristics',
isSequential: true
}
},
{
id: 'toggle-loop',
className: 'bpmn-icon-loop-marker',
title: translate('Loop'),
active: isLoop,
action: toggleLoopEntry,
options: {
loopCharacteristics: 'bpmn:StandardLoopCharacteristics'
}
}
];
return loopEntries;
};
/**
* Get the menu items containing a button for the ad hoc marker
*
* @param {djs.model.Base} element
*
* @return {Object} a menu item
*/
ReplaceMenuProvider.prototype._getAdHocEntry = function(element) {
var translate = this._translate;
var businessObject = getBusinessObject(element);
var isAdHoc = is(businessObject, 'bpmn:AdHocSubProcess');
var replaceElement = this._bpmnReplace.replaceElement;
var adHocEntry = {
id: 'toggle-adhoc',
className: 'bpmn-icon-ad-hoc-marker',
title: translate('Ad-hoc'),
active: isAdHoc,
action: function(event, entry) {
if (isAdHoc) {
return replaceElement(element, { type: 'bpmn:SubProcess' });
} else {
return replaceElement(element, { type: 'bpmn:AdHocSubProcess' });
}
}
};
return adHocEntry;
};
export var TASK = [
// {
// label: 'Task - CUSTOM',
// actionName: 'replace-with-task',
// className: 'bpmn-icon-task',
// target: {
// type: 'bpmn:Task'
// }
// }, {
// label: 'SMS Task',
// actionName: 'replace-with-sms-subprocess',
// className: 'bpmn-icon-send',
// target: {
// type: 'bpmn:Task'
// }
// }
];
import PopupMenuModule from 'diagram-js/lib/features/popup-menu';
import ReplaceModule from 'bpmn-js/lib/features/replace';
import ReplaceMenuProvider from './ReplaceMenuProvider';
export default {
__depends__: [
PopupMenuModule,
ReplaceModule
],
__init__: [ 'replaceMenuProvider' ],
replaceMenuProvider: [ 'type', ReplaceMenuProvider ]
};
import {
getBusinessObject
} from 'bpmn-js/lib/util/ModelUtil';
import {
isExpanded
} from 'bpmn-js/lib/util/DiUtil';
/**
* Returns true, if an element is from a different type
* than a target definition. Takes into account the type,
* event definition type and triggeredByEvent property.
*
* @param {djs.model.Base} element
*
* @return {Boolean}
*/
export function isDifferentType(element) {
return function(entry) {
var target = entry.target;
var businessObject = getBusinessObject(element),
eventDefinition = businessObject.eventDefinitions && businessObject.eventDefinitions[0];
var isTypeEqual = businessObject.$type === target.type;
var isEventDefinitionEqual = (
(eventDefinition && eventDefinition.$type) === target.eventDefinitionType
);
var isTriggeredByEventEqual = (
businessObject.triggeredByEvent === target.triggeredByEvent
);
var isExpandedEqual = (
target.isExpanded === undefined ||
target.isExpanded === isExpanded(businessObject)
);
return !isTypeEqual || !isEventDefinitionEqual || !isTriggeredByEventEqual || !isExpandedEqual;
};
}
import index from './index.vue';
export default index;
...@@ -228,7 +228,11 @@ ...@@ -228,7 +228,11 @@
import { TaskDesignView } from '@/layouts' import { TaskDesignView } from '@/layouts'
import BpmnModeler from 'bpmn-js/lib/Modeler' import BpmnModeler from 'bpmn-js/lib/Modeler'
import { mapGetters, mapActions } from 'vuex' import { mapGetters, mapActions } from 'vuex'
// 国际化
import customTranslate from './customTranslate/customTranslate'; import customTranslate from './customTranslate/customTranslate';
// 自定义控件
import customControlsModule from './customControls';
import customMenuProvider from './customMenuProvider';
// import propertiesPanelModule from 'bpmn-js-properties-panel' // import propertiesPanelModule from 'bpmn-js-properties-panel'
// import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda' // import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
// import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda' // import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
...@@ -350,8 +354,10 @@ ...@@ -350,8 +354,10 @@
this.modeler = new BpmnModeler({ this.modeler = new BpmnModeler({
container: '#canvas', container: '#canvas',
additionalModules: [ additionalModules: [
customTranslateModule customTranslateModule,
] customControlsModule,
customMenuProvider
]
// propertiesPanel: { // propertiesPanel: {
// parent: '#js-properties-panel' // parent: '#js-properties-panel'
// }, // },
......
# 文件夹说明
此文件夹是 `任务表单设置页面` 相关内容
import index from './index.vue';
export default index;
...@@ -469,7 +469,7 @@ ...@@ -469,7 +469,7 @@
min-width: 490px; min-width: 490px;
max-width: 490px; max-width: 490px;
position: relative; position: relative;
background: url("../../../assets/phone.png"); background: url("../../../../assets/phone.png");
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
......
# 文件夹说明
此文件夹是 `任务其他设置页面` 相关内容
import index from './index.vue';
export default index;
# 文件夹说明
此文件夹是 `任务基础设置页面` 相关内容
import index from './index.vue';
export default index;
...@@ -4,4 +4,4 @@ ...@@ -4,4 +4,4 @@
## 使用位置示例 ## 使用位置示例
![任务分组列表模块](../../../../../doc/任务分组列表模块.png) ![任务分组列表模块](../../../../../../doc/任务分组列表模块.png)
import index from './index.vue';
export default index;
...@@ -139,7 +139,7 @@ ...@@ -139,7 +139,7 @@
<script> <script>
import { PageView } from '@/layouts' import { PageView } from '@/layouts'
import ARow from 'ant-design-vue/es/grid/Row' import ARow from 'ant-design-vue/es/grid/Row'
import GroupList from './group-list' import GroupList from './components/group-list'
import { import {
deployProcess, deployProcess,
createWorkGroup, createWorkGroup,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment