@zhijiancloud/bpm 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/components/api/batch-loader.js +61 -0
  2. package/components/api/index.js +108 -0
  3. package/components/css/bpmAudit.less +13 -0
  4. package/components/css/bpmMulFile.less +9 -5
  5. package/components/css/bpmSelectEntranceForm.less +62 -0
  6. package/components/css/bpmSelectHouseOwner.less +30 -0
  7. package/components/css/bpmSignature.less +40 -0
  8. package/components/css/bpmText.less +0 -10
  9. package/components/css/common.less +43 -0
  10. package/components/css/index.less +6 -1
  11. package/components/lib/bpmAudit/src/main.vue +35 -4
  12. package/components/lib/bpmAudit/src/part/auditor/audit-new.vue +534 -0
  13. package/components/lib/bpmAudit/src/part/auditor/audit-select.vue +127 -0
  14. package/components/lib/bpmAudit/src/part/auditor/audit-with-others.vue +634 -0
  15. package/components/lib/bpmAudit/src/part/auditor.vue +54 -0
  16. package/components/lib/bpmAudit/src/part/editor.vue +7 -5
  17. package/components/lib/bpmAudit/src/part/reader.vue +10 -9
  18. package/components/lib/bpmDateTime/src/part/editor.vue +3 -1
  19. package/components/lib/bpmField/src/main.vue +5 -150
  20. package/components/lib/bpmFieldsFilter/index.js +7 -0
  21. package/components/lib/bpmFieldsFilter/src/main.vue +324 -0
  22. package/components/lib/bpmFormField/index.js +7 -0
  23. package/components/lib/bpmFormField/src/lib/form_mixin.js +818 -0
  24. package/components/lib/bpmFormField/src/lib/mixin.js +245 -0
  25. package/components/lib/bpmFormField/src/main.vue +35 -0
  26. package/components/lib/bpmMulFile/src/main.vue +0 -1
  27. package/components/lib/bpmMulFile/src/part/editor.vue +1 -1
  28. package/components/lib/bpmMulFile/src/part/reader.vue +12 -33
  29. package/components/lib/bpmMulImage/src/main.vue +1 -2
  30. package/components/lib/bpmMulImage/src/part/editor.vue +5 -1
  31. package/components/lib/bpmMulImage/src/part/reader.vue +14 -4
  32. package/components/lib/bpmNumber/src/part/editor.vue +8 -9
  33. package/components/lib/bpmSelect/src/part/reader.vue +11 -2
  34. package/components/lib/bpmSelectCheckItem/src/part/editor.vue +3 -7
  35. package/components/lib/bpmSelectEntranceForm/index.js +7 -0
  36. package/components/lib/bpmSelectEntranceForm/src/main.vue +529 -0
  37. package/components/lib/bpmSelectFromField/src/main.vue +1 -0
  38. package/components/lib/bpmSelectFromField/src/part/editor.vue +27 -13
  39. package/components/lib/bpmSelectFromForm/src/part/editor.vue +2 -5
  40. package/components/lib/bpmSelectHouseOwner/index.js +7 -0
  41. package/components/lib/bpmSelectHouseOwner/src/main.vue +102 -0
  42. package/components/lib/bpmSelectHouseOwner/src/part/editor.vue +101 -0
  43. package/components/lib/bpmSelectHouseOwner/src/part/reader.vue +17 -0
  44. package/components/lib/bpmSelectIssue/index.js +7 -0
  45. package/components/lib/bpmSelectIssue/src/main.vue +180 -0
  46. package/components/lib/bpmSignature/index.js +7 -0
  47. package/components/lib/bpmSignature/src/main.vue +248 -0
  48. package/components/lib/bpmSubForm/src/main.vue +25 -3
  49. package/components/lib/bpmTime/src/part/editor.vue +3 -2
  50. package/components/lib/field-const.js +5 -2
  51. package/components/lib/index.ts +32 -2
  52. package/components/mixins/field_base_mixin.vue +188 -0
  53. package/components/vendor/draw.js +240 -0
  54. package/dist/bpmAudit.umd.js +1 -1
  55. package/dist/bpmDateTime.umd.js +1 -1
  56. package/dist/bpmField.umd.js +7 -1
  57. package/dist/bpmField.umd.js.LICENSE.txt +2 -0
  58. package/dist/bpmFieldsFilter.umd.js +8 -0
  59. package/dist/bpmFieldsFilter.umd.js.LICENSE.txt +1 -0
  60. package/dist/bpmFormField.umd.js +8 -0
  61. package/dist/bpmFormField.umd.js.LICENSE.txt +11 -0
  62. package/dist/bpmMulFile.umd.js +1 -1
  63. package/dist/bpmMulImage.umd.js +1 -1
  64. package/dist/bpmNumber.umd.js +1 -1
  65. package/dist/bpmSelect.umd.js +1 -1
  66. package/dist/bpmSelectCheckItem.umd.js +1 -1
  67. package/dist/bpmSelectEntranceForm.umd.js +8 -0
  68. package/dist/bpmSelectEntranceForm.umd.js.LICENSE.txt +1 -0
  69. package/dist/bpmSelectFromField.umd.js +1 -1
  70. package/dist/bpmSelectFromForm.umd.js +1 -1
  71. package/dist/bpmSelectHouseOwner.umd.js +1 -0
  72. package/dist/bpmSelectIssue.umd.js +1 -0
  73. package/dist/bpmSignature.umd.js +2 -0
  74. package/dist/bpmSignature.umd.js.LICENSE.txt +9 -0
  75. package/dist/bpmSubForm.umd.js +1 -1
  76. package/dist/bpmText.umd.js +1 -1
  77. package/dist/bpmTime.umd.js +1 -1
  78. package/dist/css/bpmAudit.css +1 -0
  79. package/dist/css/bpmMulFile.css +1 -1
  80. package/dist/css/bpmSelectEntranceForm.css +1 -0
  81. package/dist/css/bpmSelectHouseOwner.css +1 -0
  82. package/dist/css/bpmSignature.css +1 -0
  83. package/dist/css/bpmText.css +1 -1
  84. package/dist/css/common.css +1 -0
  85. package/dist/css/index.css +1 -1
  86. package/dist/demo.umd.js +1 -1
  87. package/dist/demo2.umd.js +1 -1
  88. package/dist/index.umd.js +7 -1
  89. package/dist/index.umd.js.LICENSE.txt +2 -0
  90. package/package.json +25 -18
  91. package/CHANGELOG.md +0 -27
  92. package/dist/bpmDateTime.umd.js.LICENSE.txt +0 -38
  93. package/dist/bpmNumber.umd.js.LICENSE.txt +0 -38
  94. package/dist/bpmSelect.umd.js.LICENSE.txt +0 -38
  95. package/dist/bpmSelectUser.umd.js +0 -1
  96. package/dist/bpmText.umd.js.LICENSE.txt +0 -38
  97. package/dist/bpmTime.umd.js.LICENSE.txt +0 -38
@@ -6,8 +6,12 @@
6
6
  type="text">查看子表单</el-button>
7
7
  <el-table
8
8
  v-else
9
+ v-bind="$attrs"
10
+ v-on="$listeners"
9
11
  :data="subformData"
10
12
  :max-height="maxHeight"
13
+ :show-header="showHeader"
14
+ :resizable="resizable"
11
15
  border stripe
12
16
  style="width: 100%;">
13
17
  <el-table-column v-for="col in columns"
@@ -22,7 +26,7 @@
22
26
  v-model="scope.row[col.id]"
23
27
  :type="col.data.type"
24
28
  :fieldConf="col.data"
25
- :mode="mode"
29
+ :mode="col.fieldMode"
26
30
  uiType="table"
27
31
  :formDefId="formDefId"
28
32
  :orgInfo="orgInfo"
@@ -38,6 +42,8 @@
38
42
  @close="showSubForm = false">
39
43
  <div style="max-height: 70vh; overflow: auto;">
40
44
  <el-table
45
+ v-bind="$attrs"
46
+ v-on="$listeners"
41
47
  :data="subformData"
42
48
  :max-height="dialogTableMaxHeight"
43
49
  border stripe
@@ -54,7 +60,7 @@
54
60
  v-model="scope.row[col.id]"
55
61
  :type="col.data.type"
56
62
  :fieldConf="col.data"
57
- :mode="mode"
63
+ :mode="col.fieldMode"
58
64
  uiType="table"
59
65
  :formDefId="formDefId"
60
66
  :orgInfo="orgInfo"
@@ -98,6 +104,14 @@ export default {
98
104
  type: [Number, String],
99
105
  default: 500
100
106
  },
107
+ showHeader: {
108
+ type: Boolean,
109
+ default: true
110
+ },
111
+ resizable: {
112
+ type: Boolean,
113
+ default: true
114
+ },
101
115
  formDefId: {
102
116
  type: String,
103
117
  default: ''
@@ -126,7 +140,14 @@ export default {
126
140
  const arr = []
127
141
  elements.forEach(item => {
128
142
  const fieldMap = FORM_FIELDS_MAP[item.type] || {}
129
- if (fieldMap.hasBpmField) {
143
+ const fieldPermission = item.perm || {}
144
+ if (fieldMap.hasBpmField && fieldPermission.visible) {
145
+ let mode = this.mode
146
+ if (mode === 'edit' && fieldPermission.editable && fieldPermission.writable) {
147
+ mode = 'edit'
148
+ } else {
149
+ mode = 'view'
150
+ }
130
151
  arr.push({
131
152
  key: item.id,
132
153
  id: item.id,
@@ -134,6 +155,7 @@ export default {
134
155
  minWidth: fieldMap.tableColWidth || 100,
135
156
  sortable: true,
136
157
  sortBy: item.id,
158
+ fieldMode: mode,
137
159
  data: item
138
160
  })
139
161
  }
@@ -6,7 +6,8 @@
6
6
  format-model="number"
7
7
  :format="format"
8
8
  :value-format="checkFormat"
9
- :clearable="true"
9
+ :clearable="clearable"
10
+ :disabled="disabled"
10
11
  />
11
12
  </div>
12
13
  </template>
@@ -27,7 +28,7 @@ export default {
27
28
  curVal: ""
28
29
  };
29
30
  },
30
- props: ["value", "fieldConf", "row"],
31
+ props: ["value", "fieldConf", "row", "clearable", "disabled"],
31
32
  watch: {
32
33
  curVal(val) {
33
34
  this.$emit("input", val);
@@ -416,6 +416,7 @@ export const FORM_FIELDS_MAP = {
416
416
  },
417
417
  'MulSelectEntranceForm': {
418
418
  name: '远程多项选择(从入口)',
419
+ hasBpmField: true
419
420
  },
420
421
  'SelectHouseOwner': {
421
422
  name: '业主选择'
@@ -425,11 +426,13 @@ export const FORM_FIELDS_MAP = {
425
426
  },
426
427
  'MulFile': {
427
428
  name: '附件',
428
- hasBpmField: true
429
+ hasBpmField: true,
430
+ tableColWidth: 150
429
431
  },
430
432
  'MulImage': {
431
433
  name: '图片',
432
- hasBpmField: true
434
+ hasBpmField: true,
435
+ tableColWidth: 150
433
436
  },
434
437
  'Signature': {
435
438
  name: '签名',
@@ -5,6 +5,7 @@ import BpmNumber from './bpmNumber'
5
5
  import BpmDateTime from './bpmDateTime'
6
6
  import BpmMulFile from './bpmMulFile'
7
7
  import BpmField from './bpmField'
8
+ import BpmFormField from './bpmFormField'
8
9
  import BpmSelectCheckItem from './bpmSelectCheckItem'
9
10
  import BpmSelectFromField from "./bpmSelectFromField";
10
11
  import BpmSelectFromForm from "./bpmSelectFromForm";
@@ -12,6 +13,13 @@ import BpmSelectFromId from "./bpmSelectFromId";
12
13
  import BpmMulImage from "./bpmMulImage";
13
14
  import BpmSubForm from './bpmSubForm'
14
15
  import BpmAudit from './bpmAudit'
16
+ import BpmSelectEntranceForm from './bpmSelectEntranceForm'
17
+ import BpmSelectHouseOwner from './bpmSelectHouseOwner'
18
+ import BpmSignature from './bpmSignature'
19
+ import BpmSelectIssue from './bpmSelectIssue'
20
+
21
+ import BpmFieldsFilter from './bpmFieldsFilter'
22
+
15
23
  import { FORM_FIELDS_MAP } from './field-const.js'
16
24
 
17
25
  const bpmComponents = {
@@ -22,6 +30,7 @@ const bpmComponents = {
22
30
  BpmDateTime,
23
31
  BpmMulFile,
24
32
  BpmField,
33
+ BpmFormField,
25
34
  BpmSelectCheckItem,
26
35
  BpmSelectFromField,
27
36
  'BpmSelectUser': BpmSelectFromField,
@@ -33,7 +42,13 @@ const bpmComponents = {
33
42
  BpmSelectFromId,
34
43
  BpmMulImage,
35
44
  BpmSubForm,
36
- BpmAudit
45
+ BpmAudit,
46
+ BpmSelectEntranceForm,
47
+ BpmSelectHouseOwner,
48
+ BpmSignature,
49
+ BpmSelectIssue,
50
+
51
+ BpmFieldsFilter
37
52
  }
38
53
 
39
54
  const install: any = function (Vue: any) {
@@ -51,19 +66,34 @@ const bpmConsts = {
51
66
  // 供局部引入
52
67
  export {
53
68
  BpmField,
69
+ BpmFormField,
54
70
  BpmText,
55
71
  BpmNumber,
56
72
  BpmTime,
57
73
  BpmDateTime,
74
+ BpmSelect,
75
+ BpmMulImage,
76
+ BpmMulFile,
58
77
  BpmSubForm,
59
78
  BpmAudit,
79
+ BpmSignature,
80
+
81
+ BpmSelectEntranceForm,
82
+ BpmSelectFromForm,
83
+ BpmSelectFromId,
84
+ BpmSelectFromField,
85
+ BpmSelectCheckItem,
86
+ BpmSelectHouseOwner,
87
+ BpmSelectIssue,
88
+
89
+ BpmFieldsFilter,
60
90
 
61
91
  bpmConsts
62
92
  }
63
93
 
64
94
  // 供全局引入
65
95
  export default {
66
- version: '0.0.6',
96
+ version: '0.0.7',
67
97
  install,
68
98
 
69
99
  bpmConsts: { // 兼容,后续bpm_data改为局部使用后弃用
@@ -0,0 +1,188 @@
1
+ <script>
2
+ import _ from "lodash";
3
+
4
+ // 获取BPM组件文件引用上下文
5
+ const BpmComponentRequire = require.context(
6
+ "../lib",
7
+ true,
8
+ /index.(js|ts)$/
9
+ )
10
+
11
+ const bpmComponents = {};
12
+
13
+ //动态引用
14
+ BpmComponentRequire.keys().forEach(filePath => {
15
+ let _tmp = filePath.split("/");
16
+
17
+ if(!(filePath.includes('bpmField') || filePath.includes('bpmFormField'))){
18
+ bpmComponents[_tmp[1]] = BpmComponentRequire(filePath).default
19
+ console.log("bpmComponents",bpmComponents)
20
+ }
21
+ })
22
+
23
+ const COMPONTENTMAP = {
24
+ // 'Signature': 'MulImage',
25
+ 'SerialNumber': 'Text',
26
+ 'Date': 'DateTime',
27
+ 'TextArea': 'Text',
28
+ 'MulSelect': 'Select',
29
+ 'Status': 'Select',
30
+ 'MulImg': 'MulFile',
31
+ 'MulSelectCheckItem': 'SelectCheckItem',
32
+ 'MulSelectFromField': 'SelectFromField',
33
+ 'SelectUser': 'SelectFromField',
34
+ 'MulSelectUser': 'SelectFromField',
35
+ 'SelectPartner': 'SelectFromField',
36
+ 'MulSelectPartner': 'SelectFromField',
37
+ 'SelectProject': 'SelectFromField',
38
+ 'MulSelectProject': 'SelectFromField',
39
+ 'SelectOrg': 'SelectFromField',
40
+ 'MulSelectOrg': 'SelectFromField',
41
+ 'MulSelectFromForm': 'SelectFromForm',
42
+ 'MulSelectFromId': 'SelectFromId',
43
+ 'MulSelectURUser': 'SelectFromField',
44
+ 'SelectURUser': 'SelectFromField',
45
+ 'SelectRootCategory': 'SelectFromField',
46
+ 'MulSelectSort': 'SelectCheckItem',
47
+ 'SelectSort': 'SelectCheckItem',
48
+ 'MulSelectEntranceForm': 'SelectEntranceForm',
49
+ 'MulSelectIssue': 'SelectIssue',
50
+ 'XSubForm': 'SubForm',
51
+ 'OrderSubform': 'SubForm'
52
+ }
53
+
54
+ export default {
55
+ components: bpmComponents,
56
+ props: {
57
+ value: {
58
+ type: [String, Array, Number, Object],
59
+
60
+ },
61
+ type: {
62
+ type: String,
63
+ default: ''
64
+ },
65
+ fieldConf: {
66
+ type: Object,
67
+ default() {
68
+ return {};
69
+ },
70
+ },
71
+ row: {
72
+ type: Object,
73
+ default() {
74
+ return {};
75
+ },
76
+ },
77
+ mode: {
78
+ type: String,
79
+ default: 'view' // view, edit
80
+ },
81
+ uiType: {
82
+ type: String,
83
+ default: 'default' // default,table,form,search
84
+ },
85
+ formDefId: {
86
+ type: String,
87
+ default: ''
88
+ },
89
+ orgInfo: {
90
+ type: Object,
91
+ default () {
92
+ return {
93
+ level: 'group', // group,team,project
94
+ level_id: 0,
95
+ group_id: 0
96
+ }
97
+ }
98
+ },
99
+ clearable: { // 仅对mode=edit有效
100
+ type: Boolean,
101
+ default: false
102
+ },
103
+ disabled: { // 仅对mode=edit有效
104
+ type: Boolean,
105
+ default: false
106
+ },
107
+ isMultiple: {
108
+ type: Boolean,
109
+ default() {
110
+ return false;
111
+ },
112
+ },
113
+ dm: {
114
+ type: Boolean,
115
+ default() {
116
+ return false;
117
+ }
118
+ },
119
+ },
120
+ data () {
121
+ return {
122
+ curVal: ""
123
+ }
124
+ },
125
+ watch: {
126
+ curVal(val){
127
+ this.$emit("input", val)
128
+ this.$emit("change", val)
129
+ },
130
+ value: {
131
+ handler () {
132
+ this.curVal = this.value
133
+ },
134
+ immediate: true
135
+ },
136
+ dm(val){
137
+ this.$bpm.isDm = val
138
+ }
139
+ },
140
+ computed: {
141
+ curComponent() {
142
+ let componentType = this.type || _.get(this.fieldConf, "type");
143
+ const map = COMPONTENTMAP
144
+ componentType = map[componentType] || componentType
145
+
146
+ if (this.dm && componentType === 'Signature') {
147
+ componentType = 'MulImage'
148
+ }
149
+
150
+ if (!bpmComponents[`bpm${componentType}`]) return
151
+
152
+ return `Bpm${componentType}`;
153
+ },
154
+ componentType(){
155
+ return this.type || _.get(this.fieldConf, "type")
156
+ },
157
+ isMul() {
158
+ let type = this.componentType
159
+ let isContainMul = type && type.indexOf("Mul") > -1;
160
+ return this.isMultiple || isContainMul
161
+ },
162
+ // 同一个form中,不同字段的mode可能不同,需结合其 fieldConf.perm 决定
163
+ fieldMode () {
164
+ let mode = this.mode
165
+ const fieldPermission = this.fieldConf.perm || {}
166
+ if (!fieldPermission.editable || !fieldPermission.writable) {
167
+ mode = 'view'
168
+ }
169
+ return mode
170
+ },
171
+ fieldDisabled () {
172
+ let disabled = this.disabled
173
+ const fieldPermission = this.fieldConf.perm
174
+ if (this.fieldMode === 'edit' && fieldPermission && !fieldPermission.writable) {
175
+ disabled = true
176
+ }
177
+
178
+ return disabled
179
+ }
180
+ },
181
+ mounted () {
182
+ this.$bpm.env.form_name = this.formDefId
183
+ this.curVal = this.value
184
+ this.$bpm.orgInfo = this.orgInfo
185
+ this.$bpm.isDm = this.dm
186
+ }
187
+ };
188
+ </script>
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Created by louizhai on 17/6/30.
3
+ * description: Use canvas to draw.
4
+ */
5
+ function Draw(canvas, degree, config = {}, boxStyle = {}) {
6
+ if (!(this instanceof Draw)) {
7
+ return new Draw(canvas, config);
8
+ }
9
+ if (!canvas) {
10
+ return;
11
+ }
12
+ let { width, height } = window.getComputedStyle(canvas, null);
13
+ width = width.replace('px', '');
14
+ height = height.replace('px', '');
15
+
16
+ this.canvas = canvas;
17
+ this.context = canvas.getContext('2d');
18
+ this.width = width;
19
+ this.height = height;
20
+ const context = this.context;
21
+
22
+ // 根据设备像素比优化canvas绘图
23
+ const devicePixelRatio = window.devicePixelRatio;
24
+ if (devicePixelRatio) {
25
+ canvas.style.width = `${width}px`;
26
+ canvas.style.height = `${height}px`;
27
+ canvas.height = height * devicePixelRatio;
28
+ canvas.width = width * devicePixelRatio;
29
+ context.scale(devicePixelRatio, devicePixelRatio);
30
+ } else {
31
+ canvas.width = width;
32
+ canvas.height = height;
33
+ }
34
+
35
+
36
+ context.lineWidth = 2;
37
+ context.strokeStyle = 'black';
38
+ context.lineCap = 'round';
39
+ context.lineJoin = 'round';
40
+ Object.assign(context, config);
41
+
42
+
43
+ const point = {};
44
+ const isMobile = /phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/i.test(navigator.userAgent);
45
+ // 移动端性能太弱, 去掉模糊以提高手写渲染速度
46
+ if (!isMobile) {
47
+ context.shadowBlur = 1;
48
+ context.shadowColor = 'black';
49
+ }
50
+ let pressed = false;
51
+
52
+ const paint = (signal) => {
53
+ switch (signal) {
54
+ case 1:
55
+ context.beginPath();
56
+ context.moveTo(point.x, point.y);
57
+ break
58
+ case 2:
59
+ context.lineTo(point.x, point.y);
60
+ context.stroke();
61
+ break;
62
+ default: break
63
+ }
64
+ };
65
+ const create = signal => (e) => {
66
+ e.preventDefault();
67
+ if (signal === 1) {
68
+ pressed = true;
69
+ }
70
+ if (signal === 1 || pressed) {
71
+ const { left, top } = canvas.getBoundingClientRect();
72
+ e = isMobile ? e.touches[0] : e;
73
+ point.x = e.clientX - left + 0.5;
74
+ point.y = e.clientY - top + 0.5;
75
+ paint(signal);
76
+ }
77
+ };
78
+ const start = create(1);
79
+ const move = create(2);
80
+ const requestAnimationFrame = window.requestAnimationFrame;
81
+ const optimizedMove = requestAnimationFrame ? (e) => {
82
+ requestAnimationFrame(() => {
83
+ move(e);
84
+ });
85
+ } : move;
86
+
87
+ if (isMobile) {
88
+ canvas.addEventListener('touchstart', start);
89
+ canvas.addEventListener('touchmove', optimizedMove);
90
+ } else {
91
+ canvas.addEventListener('mousedown', start);
92
+ canvas.addEventListener('mousemove', optimizedMove);
93
+ ['mouseup', 'mouseleave'].forEach((event) => {
94
+ canvas.addEventListener(event, () => {
95
+ pressed = false;
96
+ });
97
+ });
98
+ }
99
+
100
+ // 重置画布坐标系
101
+ if (typeof degree === 'number') {
102
+ this.degree = degree;
103
+ context.rotate((degree * Math.PI) / 180);
104
+ switch (degree) {
105
+ case -90:
106
+ context.translate(-height, 0);
107
+ break;
108
+ case 90:
109
+ context.translate(0, -width);
110
+ break;
111
+ case -180:
112
+ case 180:
113
+ context.translate(-width, -height);
114
+ break;
115
+ default:
116
+ }
117
+ }
118
+ }
119
+ Draw.prototype = {
120
+ scale(width, height, canvas = this.canvas) {
121
+ const w = canvas.width;
122
+ const h = canvas.height;
123
+ width = width || w;
124
+ height = height || h;
125
+ if (width !== w || height !== h) {
126
+ const tmpCanvas = document.createElement('canvas');
127
+ const tmpContext = tmpCanvas.getContext('2d');
128
+ tmpCanvas.width = width;
129
+ tmpCanvas.height = height;
130
+ tmpContext.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
131
+ canvas = tmpCanvas;
132
+ }
133
+ return canvas;
134
+ },
135
+ rotate(degree, image = this.canvas) {
136
+ degree = ~~degree;
137
+ if (degree !== 0) {
138
+ const maxDegree = 180;
139
+ const minDegree = -90;
140
+ if (degree > maxDegree) {
141
+ degree = maxDegree;
142
+ } else if (degree < minDegree) {
143
+ degree = minDegree;
144
+ }
145
+
146
+ const canvas = document.createElement('canvas');
147
+ const context = canvas.getContext('2d');
148
+ const height = image.height;
149
+ const width = image.width;
150
+ const degreePI = (degree * Math.PI) / 180;
151
+
152
+ switch (degree) {
153
+ // 逆时针旋转90°
154
+ case -90:
155
+ canvas.width = height;
156
+ canvas.height = width;
157
+ context.rotate(degreePI);
158
+ context.drawImage(image, -width, 0);
159
+ break;
160
+ // 顺时针旋转90°
161
+ case 90:
162
+ canvas.width = height;
163
+ canvas.height = width;
164
+ context.rotate(degreePI);
165
+ context.drawImage(image, 0, -height);
166
+ break;
167
+ // 顺时针旋转180°
168
+ case 180:
169
+ canvas.width = width;
170
+ canvas.height = height;
171
+ context.rotate(degreePI);
172
+ context.drawImage(image, -width, -height);
173
+ break;
174
+ default:
175
+ }
176
+ image = canvas;
177
+ }
178
+ return image;
179
+ },
180
+ getPNGImage(canvas = this.canvas) {
181
+ return canvas.toDataURL('image/png');
182
+ },
183
+ getJPGImage(canvas = this.canvas) {
184
+ return canvas.toDataURL('image/jpeg', 0.5);
185
+ },
186
+ downloadPNGImage(image) {
187
+ const url = image.replace('image/png', 'image/octet-stream;Content-Disposition:attachment;filename=test.png');
188
+ window.location.href = url;
189
+ },
190
+ dataURLtoBlob(dataURL) {
191
+ const arr = dataURL.split(',');
192
+ const mime = arr[0].match(/:(.*?);/)[1];
193
+ const bStr = atob(arr[1]);
194
+ let n = bStr.length;
195
+ const u8arr = new Uint8Array(n);
196
+ while (n--) {
197
+ u8arr[n] = bStr.charCodeAt(n);
198
+ }
199
+ return new Blob([u8arr], { type: mime });
200
+ },
201
+ clear() {
202
+ let width;
203
+ let height;
204
+ switch (this.degree) {
205
+ case -90:
206
+ case 90:
207
+ width = this.height;
208
+ height = this.width;
209
+ break;
210
+ default:
211
+ width = this.width;
212
+ height = this.height;
213
+ }
214
+ this.context.clearRect(0, 0, width, height);
215
+ },
216
+ upload(blob, url, success, failure) {
217
+ const formData = new FormData();
218
+ const xhr = new XMLHttpRequest();
219
+ xhr.withCredentials = true;
220
+ formData.append('image', blob, 'sign');
221
+
222
+ xhr.open('POST', url, true);
223
+ xhr.onload = () => {
224
+ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
225
+ success(xhr.responseText);
226
+ } else {
227
+ failure();
228
+ }
229
+ };
230
+ xhr.onerror = (e) => {
231
+ if (typeof failure === 'function') {
232
+ failure(e);
233
+ } else {
234
+ console.log(`upload img error: ${e}`);
235
+ }
236
+ };
237
+ xhr.send(formData);
238
+ },
239
+ };
240
+ export default Draw;