wy-editor 1.0.0 → 1.0.3

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 (39) hide show
  1. package/dist/demo.html +1 -0
  2. package/dist/fonts/element-icons.f1a45d74.ttf +0 -0
  3. package/dist/fonts/element-icons.ff18efd1.woff +0 -0
  4. package/dist/wy-editor.common.js +109385 -0
  5. package/dist/wy-editor.common.js.map +1 -0
  6. package/dist/wy-editor.css +1 -0
  7. package/dist/wy-editor.umd.js +109396 -0
  8. package/dist/wy-editor.umd.js.map +1 -0
  9. package/dist/wy-editor.umd.min.js +47 -0
  10. package/dist/wy-editor.umd.min.js.map +1 -0
  11. package/package.json +9 -4
  12. package/.browserslistrc +0 -3
  13. package/babel.config.js +0 -5
  14. package/jsconfig.json +0 -19
  15. package/public/favicon.ico +0 -0
  16. package/public/index.html +0 -17
  17. package/src/App.vue +0 -127
  18. package/src/assets/logo.png +0 -0
  19. package/src/components/FieldVariable.vue +0 -104
  20. package/src/components/FormulaList.vue +0 -132
  21. package/src/core/calculate.js +0 -90
  22. package/src/core/functionCore.js +0 -92
  23. package/src/core/index.js +0 -249
  24. package/src/formula/base.js +0 -11
  25. package/src/formula/frequentlyUse/formula.json +0 -30
  26. package/src/formula/frequentlyUse/index.js +0 -13
  27. package/src/formula/index.js +0 -12
  28. package/src/formula/mathFormula/formula.json +0 -142
  29. package/src/formula/mathFormula/index.js +0 -13
  30. package/src/formula/statistics/formula.json +0 -30
  31. package/src/formula/statistics/index.js +0 -13
  32. package/src/formula/stringData/formula.json +0 -93
  33. package/src/formula/stringData/index.js +0 -13
  34. package/src/index.js +0 -5
  35. package/src/index.vue +0 -219
  36. package/src/main.js +0 -14
  37. package/src/router/index.js +0 -14
  38. package/src/utils/index.js +0 -35
  39. package/vue.config.js +0 -4
package/src/core/index.js DELETED
@@ -1,249 +0,0 @@
1
- import { generateRandomData } from '../utils'
2
- import { calculate } from './calculate'
3
-
4
- export default class FormulaEditorCore {
5
- editor = null // 编辑器实例
6
- formulaObjList = [] // 公式对象列表
7
- text = '' // 公式文本
8
- marks = [] // 需替换的变量列表
9
- listen = ['change', 'inputRead', 'beforeChange'] // 监听方法
10
-
11
- constructor(editor, text = '', formulaObjList = []) {
12
- this.editor = editor
13
- this.text = text
14
- this.formulaObjList = formulaObjList
15
- }
16
-
17
- // 获取公式列表
18
- getFormulaList() {
19
- return this.formulaObjList.flatMap(o => o.formula)
20
- }
21
-
22
- // 数据回显
23
- renderData(formulaData) {
24
- if (Object.keys(formulaData).length === 0) return
25
-
26
- this.editor.setValue(formulaData.text)
27
- this.marks = formulaData.marks
28
- this.marks.forEach(o => {
29
- this.editor.doc.markText(o.from, o.to, {
30
- className: 'cm-field',
31
- attributes: {
32
- 'data-menuId': o.menuId,
33
- 'data-enCode': o.enCode,
34
- },
35
- atomic: true,
36
- })
37
- })
38
- }
39
-
40
- // 校验公式
41
- validateFormula(fieldList) {
42
- const variable = fieldList.reduce((acc, cur) => {
43
- acc[cur.enCode] = generateRandomData(cur.value)
44
- return acc
45
- }, {})
46
- const result = calculate({ ...this.getData(), value: variable })
47
- const calculateResult = result.toString().includes('Error: #VALUE!')
48
- if (calculateResult) {
49
- return { error: true, message: '公式计算错误,请检查公式' }
50
- }
51
- if (result.error) {
52
- return result
53
- }
54
- return { error: false }
55
- }
56
-
57
- // 注册监听器
58
- registerListen() {
59
- for (const item of this.listen) {
60
- const fn = this[`on${item.charAt(0).toUpperCase()}${item.slice(1)}`]
61
- this.editor.on(item, fn.bind(this, ...arguments))
62
- }
63
- }
64
-
65
- onInputRead(cm, change) {
66
- cm.showHint({
67
- hint: this.customHint.bind(this),
68
- completeSingle: false,
69
- })
70
- }
71
-
72
- getData() {
73
- return {
74
- text: this.text,
75
- marks: this.marks,
76
- }
77
- }
78
-
79
- reset() {
80
- this.editor.setValue('')
81
- this.text = ''
82
- this.marks = []
83
- }
84
-
85
- // 当编辑器中文本内容改变
86
- onChange(cm, changeObj) {
87
- this.marks = cm
88
- .getAllMarks()
89
- .filter(o => o.className === 'cm-field')
90
- .map(marks => {
91
- const { attributes } = marks
92
- return {
93
- ...marks.find(),
94
- enCode: attributes['data-enCode'],
95
- menuId: attributes['data-menuId'],
96
- }
97
- })
98
- this.text = cm.getValue()
99
- if (changeObj.origin === 'complete') {
100
- // 向左移动一个字符
101
- this.moveCursor('left', 1)
102
- }
103
- }
104
-
105
- /**
106
- * 插入文本
107
- * @param {string | object} text
108
- * @param {'formula' | 'field'} type
109
- */
110
- insertText(data, type) {
111
- const cursor = this.editor.getCursor()
112
-
113
- this.editor.replaceRange(
114
- type === 'field' ? JSON.stringify(data) : data,
115
- cursor
116
- )
117
- type === 'formula' && this.moveCursor('left', 1)
118
- this.editor.focus()
119
- }
120
-
121
- /**
122
- *
123
- * @param {'left' | 'right' | 'up' | 'down'} direction 方向
124
- * @param {number} step 步长
125
- */
126
- moveCursor(direction, step) {
127
- const cursor = this.editor.getCursor()
128
- const line = cursor.line
129
- const ch = cursor.ch
130
-
131
- // 检查是否已经在行首
132
- if (direction === 'left') {
133
- // 如果不是行首,则向左移动字符
134
- this.editor.setCursor({ line: line, ch: ch - step })
135
- } else if (direction === 'right') {
136
- // 如果是行首,则向右移动字符
137
- this.editor.setCursor({ line: line, ch: ch + step })
138
- } else if (direction === 'up') {
139
- // 如果是行首,则向上移动行
140
- this.editor.setCursor({ line: line - step, ch: ch })
141
- } else if (direction === 'down') {
142
- // 如果是行首,则向下移动行
143
- this.editor.setCursor({ line: line + step, ch: ch })
144
- }
145
- }
146
-
147
- onBeforeChange(cm, changeObj) {
148
- const { text, from, cancel } = changeObj
149
- const data = this.matchField(text[0])
150
- if (data.length) {
151
- cancel()
152
- const field = JSON.parse(data[0])
153
- const fieldFrom = { ...from }
154
- const to = { ...from, ch: from.ch + field.fullName.length }
155
- cm.replaceRange(field.fullName, fieldFrom)
156
- cm.doc.markText(fieldFrom, to, {
157
- className: 'cm-field',
158
- attributes: {
159
- 'data-menuId': field.menuId,
160
- 'data-enCode': field.enCode,
161
- },
162
- atomic: true,
163
- })
164
- }
165
- }
166
-
167
- // 匹配字段
168
- matchField(text) {
169
- const regex = /\{[^}]+\}/g
170
- return text.match(regex) || []
171
- }
172
-
173
- // 匹配当前行的公式
174
- matchWord(text) {
175
- // 使用正则表达式提取出字母部分
176
- const match = text.match(/[a-zA-Z]+$/)
177
- return match ? match[0] : ''
178
- }
179
-
180
- // 匹配当前行的公式
181
- matchFormula(text) {
182
- if (!text) return false
183
-
184
- const suggestions = this.getFormulaList()
185
- const match = suggestions.find(o => o.name === text)
186
- return match
187
- }
188
-
189
- // 自定义提示函数
190
- customHint(cm) {
191
- // 游标
192
- const cursor = cm.getCursor()
193
- // 当前行文本
194
- const currentLineText = cm.getLine(cursor.line)
195
- const matchWords = this.matchWord(currentLineText)
196
- const start = cursor.ch
197
- const suggestions = this.getFormulaList()
198
- const result = {
199
- list: suggestions
200
- .map(o => ({ text: `${o.name}()`, displayText: o.name, tip: o.tip }))
201
- .filter(
202
- suggestion =>
203
- matchWords &&
204
- suggestion.text.toLowerCase().includes(matchWords.toLowerCase())
205
- )
206
- .map(suggestion => {
207
- const text = suggestion.displayText
208
- const matchIndex = text
209
- .toLowerCase()
210
- .indexOf(matchWords.toLowerCase())
211
- suggestion.render = function (element, self, data) {
212
- if (matchIndex >= 0) {
213
- const beforeMatch = text.slice(0, matchIndex)
214
- const match = text.slice(
215
- matchIndex,
216
- matchIndex + matchWords.length
217
- )
218
- const afterMatch = text.slice(matchIndex + matchWords.length)
219
-
220
- const span = document.createElement('span')
221
-
222
- if (beforeMatch) {
223
- span.appendChild(document.createTextNode(beforeMatch))
224
- }
225
-
226
- const highlight = document.createElement('span')
227
- highlight.textContent = match
228
- highlight.style.fontWeight = 'bold'
229
- highlight.style.color = '#ff0000'
230
- span.appendChild(highlight)
231
-
232
- if (afterMatch) {
233
- span.appendChild(document.createTextNode(afterMatch))
234
- }
235
-
236
- element.appendChild(span)
237
- } else {
238
- element.appendChild(document.createTextNode(text))
239
- }
240
- }
241
-
242
- return suggestion
243
- }),
244
- from: { line: cursor.line, ch: start - matchWords.length },
245
- to: { line: cursor.line, ch: start },
246
- }
247
- return result
248
- }
249
- }
@@ -1,11 +0,0 @@
1
- export default class BaseFormula {
2
- name = ''
3
- formula = []
4
- enCode = ''
5
- constructor (params) {
6
- const { name, formula, enCode } = params
7
- this.name = name
8
- this.formula = formula
9
- this.enCode = enCode
10
- }
11
- }
@@ -1,30 +0,0 @@
1
- [
2
- {
3
- "name": "CONCATENATE",
4
- "enCode": "CONCATENATE",
5
- "tip": "合并多个文本",
6
- "example": "CONCATENATE(\"Hello\",\"World\") = \"HelloWorld\"",
7
- "usage": "CONCATENATE(文本1,文本2,...)。"
8
- },
9
- {
10
- "name": "SUM",
11
- "enCode": "SUM",
12
- "tip": "求和",
13
- "example": "SUM(数学成绩,语文成绩,英语成绩,...) = 各科总成绩",
14
- "usage": "SUM(数值1,数值2,...)。"
15
- },
16
- {
17
- "name": "DATE",
18
- "enCode": "DATE",
19
- "tip": "返回特定日期",
20
- "example": "DATE(2021,1,1)",
21
- "usage": "DATE(year,month,day)。"
22
- },
23
- {
24
- "name": "IF",
25
- "enCode": "IF",
26
- "tip": "条件判断",
27
- "example": "IF(成绩>60,'及格','不及格')",
28
- "usage": "IF(逻辑语句,真值,假值)。"
29
- }
30
- ]
@@ -1,13 +0,0 @@
1
- // 常用函数
2
- import BaseFormula from '../base'
3
- import formula from './formula.json'
4
-
5
- export default class FrequentlyUse extends BaseFormula {
6
- constructor () {
7
- super({
8
- name: '常用函数',
9
- enCode: 'frequentlyUse',
10
- formula,
11
- })
12
- }
13
- }
@@ -1,12 +0,0 @@
1
- import frequentlyUse from './frequentlyUse'
2
- import mathFormula from './mathFormula'
3
- import statistics from './statistics'
4
- import stringData from './stringData'
5
-
6
- export default [
7
- // 常用函数
8
- frequentlyUse,
9
- mathFormula,
10
- statistics,
11
- stringData,
12
- ]
@@ -1,142 +0,0 @@
1
- [
2
- {
3
- "name": "ABS",
4
- "enCode": "ABS",
5
- "tip": "返回数字的绝对值",
6
- "example": "Abs(-5) = 5",
7
- "usage": "Abs(number)"
8
- },
9
- {
10
- "name": "Ceiling",
11
- "enCode": "Ceiling",
12
- "tip": "向上舍入到最接近的整数",
13
- "example": "Ceiling(4.2) = 5",
14
- "usage": "Ceiling(number)"
15
- },
16
- {
17
- "name": "Floor",
18
- "enCode": "Floor",
19
- "tip": "向下舍入到最接近的整数",
20
- "example": "Floor(4.7) = 4",
21
- "usage": "Floor(number)"
22
- },
23
- {
24
- "name": "Round",
25
- "enCode": "Round",
26
- "tip": "四舍五入到指定小数位数",
27
- "example": "Round(4.5) = 4(银行家舍入法)",
28
- "usage": "Round(number, [decimals])"
29
- },
30
- {
31
- "name": "Round",
32
- "enCode": "Round1",
33
- "tip": "四舍五入到整数",
34
- "example": "Round(4.5, 0) = 4",
35
- "usage": "Round(number, 0)"
36
- },
37
- {
38
- "name": "Truncate",
39
- "enCode": "Truncate",
40
- "tip": "截断数字的小数部分",
41
- "example": "Truncate(4.7) = 4",
42
- "usage": "Truncate(number)"
43
- },
44
- {
45
- "name": "Sign",
46
- "enCode": "Sign",
47
- "tip": "返回数字的符号",
48
- "example": "Sign(-10) = -1",
49
- "usage": "Sign(number)"
50
- },
51
- {
52
- "name": "Sin",
53
- "enCode": "Sin",
54
- "tip": "返回角度的正弦值",
55
- "example": "Sin(PI/2) = 1",
56
- "usage": "Sin(angle)"
57
- },
58
- {
59
- "name": "Cos",
60
- "enCode": "Cos",
61
- "tip": "返回角度的余弦值",
62
- "example": "Cos(0) = 1",
63
- "usage": "Cos(angle)"
64
- },
65
- {
66
- "name": "Tan",
67
- "enCode": "Tan",
68
- "tip": "返回角度的正切值",
69
- "example": "Tan(PI/4) ≈ 1",
70
- "usage": "Tan(angle)"
71
- },
72
- {
73
- "name": "Asin",
74
- "enCode": "Asin",
75
- "tip": "返回反正弦值",
76
- "example": "Asin(1) = PI/2",
77
- "usage": "Asin(number)"
78
- },
79
- {
80
- "name": "ACos",
81
- "enCode": "ACos",
82
- "tip": "返回反余弦值",
83
- "example": "ACos(0) = PI/2",
84
- "usage": "ACos(number)"
85
- },
86
- {
87
- "name": "Atan",
88
- "enCode": "Atan",
89
- "tip": "返回反正切值",
90
- "example": "Atan(1) = PI/4",
91
- "usage": "Atan(number)"
92
- },
93
- {
94
- "name": "Atan2",
95
- "enCode": "Atan2",
96
- "tip": "返回两个数字的反正切值",
97
- "example": "Atan2(1, 1) = PI/4",
98
- "usage": "Atan2(y, x)"
99
- },
100
- {
101
- "name": "Pow",
102
- "enCode": "Pow",
103
- "tip": "返回指定数字的指定次幂",
104
- "example": "Pow(2, 3) = 8",
105
- "usage": "Pow(base, exponent)"
106
- },
107
- {
108
- "name": "Sqrt",
109
- "enCode": "Sqrt",
110
- "tip": "返回数字的平方根",
111
- "example": "Sqrt(16) = 4",
112
- "usage": "Sqrt(number)"
113
- },
114
- {
115
- "name": "Exp",
116
- "enCode": "Exp",
117
- "tip": "返回e的指定次幂",
118
- "example": "Exp(1) ≈ 2.71828",
119
- "usage": "Exp(exponent)"
120
- },
121
- {
122
- "name": "Log",
123
- "enCode": "Log",
124
- "tip": "返回指定底数的对数",
125
- "example": "Log(100, 10) = 2",
126
- "usage": "Log(number, base)"
127
- },
128
- {
129
- "name": "Log10",
130
- "enCode": "Log10",
131
- "tip": "返回以10为底的对数",
132
- "example": "Log10(100) = 2",
133
- "usage": "Log10(number)"
134
- },
135
- {
136
- "name": "Ln",
137
- "enCode": "Ln",
138
- "tip": "返回自然对数(以e为底)",
139
- "example": "Ln(E) = 1",
140
- "usage": "Ln(number)"
141
- }
142
- ]
@@ -1,13 +0,0 @@
1
- // 数学函数
2
- import BaseFormula from '../base'
3
- import formula from './formula.json'
4
-
5
- export default class MathFormula extends BaseFormula {
6
- constructor () {
7
- super({
8
- name: '数学函数',
9
- enCode: 'math',
10
- formula,
11
- })
12
- }
13
- }
@@ -1,30 +0,0 @@
1
- [
2
- {
3
- "name": "AVERAGE",
4
- "enCode": "AVERAGE",
5
- "tip": "计算平均值",
6
- "example": "AVERAGE(数学成绩,语文成绩,英语成绩,...) = 平均成绩",
7
- "usage": "AVERAGE(数值1,数值2,...)。"
8
- },
9
- {
10
- "name": "MIN",
11
- "enCode": "MIN",
12
- "tip": "求最小值",
13
- "example": "MIN(10,20,30,5,15) = 5",
14
- "usage": "MIN(数值1,数值2,...)。"
15
- },
16
- {
17
- "name": "MAX",
18
- "enCode": "MAX",
19
- "tip": "求最大值",
20
- "example": "MAX(10,20,30,5,15) = 30",
21
- "usage": "MAX(数值1,数值2,...)。"
22
- },
23
- {
24
- "name": "COUNT",
25
- "enCode": "COUNT",
26
- "tip": "计数",
27
- "example": "COUNT(学生1,学生2,学生3,...,学生n) = 学生总数",
28
- "usage": "COUNT(值1,值2,...)。"
29
- }
30
- ]
@@ -1,13 +0,0 @@
1
- // 统计函数
2
- import BaseFormula from '../base'
3
- import formula from './formula.json'
4
-
5
- export default class MathFormula extends BaseFormula {
6
- constructor () {
7
- super({
8
- name: '统计函数',
9
- enCode: 'statistics',
10
- formula,
11
- })
12
- }
13
- }
@@ -1,93 +0,0 @@
1
- [
2
- {
3
- "name": "CONCAT",
4
- "enCode": "CONCAT",
5
- "tip": "合并多个文本",
6
- "example": "CONCAT(\"Hello\",\"World\") = \"HelloWorld\"",
7
- "usage": "CONCAT(文本1,文本2,...)。"
8
- },
9
- {
10
- "name": "LENGTH",
11
- "enCode": "LENGTH",
12
- "tip": "返回文本长度",
13
- "example": "LENGTH(\"Hello\") = 5",
14
- "usage": "LENGTH(文本)。"
15
- },
16
- {
17
- "name": "SUBSTRING",
18
- "enCode": "SUBSTRING",
19
- "tip": "提取子字符串",
20
- "example": "SUBSTRING(\"HelloWorld\",1,5) = \"Hello\"",
21
- "usage": "SUBSTRING(文本,开始位置,长度)。"
22
- },
23
- {
24
- "name": "TOUPPER",
25
- "enCode": "TOUPPER",
26
- "tip": "转换为大写",
27
- "example": "TOUPPER(\"hello\") = \"HELLO\"",
28
- "usage": "TOUPPER(文本)。"
29
- },
30
- {
31
- "name": "TOLOWER",
32
- "enCode": "TOLOWER",
33
- "tip": "转换为小写",
34
- "example": "TOLOWER(\"HELLO\") = \"hello\"",
35
- "usage": "TOLOWER(文本)。"
36
- },
37
- {
38
- "name": "TRIM",
39
- "enCode": "TRIM",
40
- "tip": "去除首尾空格",
41
- "example": "TRIM(\" Hello \") = \"Hello\"",
42
- "usage": "TRIM(文本)。"
43
- },
44
- {
45
- "name": "REPLACE",
46
- "enCode": "REPLACE",
47
- "tip": "替换文本中的字符",
48
- "example": "REPLACE(\"HelloWorld\",\"World\",\"Java\") = \"HelloJava\"",
49
- "usage": "REPLACE(文本,旧文本,新文本)。"
50
- },
51
- {
52
- "name": "INDEXOF",
53
- "enCode": "INDEXOF",
54
- "tip": "查找字符位置",
55
- "example": "INDEXOF(\"HelloWorld\",\"World\") = 6",
56
- "usage": "INDEXOF(文本,查找内容)。"
57
- },
58
- {
59
- "name": "CONTAINS",
60
- "enCode": "CONTAINS",
61
- "tip": "判断是否包含文本",
62
- "example": "CONTAINS(\"HelloWorld\",\"World\") = true",
63
- "usage": "CONTAINS(文本,查找内容)。"
64
- },
65
- {
66
- "name": "STARTSWITH",
67
- "enCode": "STARTSWITH",
68
- "tip": "判断是否以指定文本开头",
69
- "example": "STARTSWITH(\"HelloWorld\",\"Hello\") = true",
70
- "usage": "STARTSWITH(文本,开头文本)。"
71
- },
72
- {
73
- "name": "ENDSWITH",
74
- "enCode": "ENDSWITH",
75
- "tip": "判断是否以指定文本结尾",
76
- "example": "ENDSWITH(\"HelloWorld\",\"World\") = true",
77
- "usage": "ENDSWITH(文本,结尾文本)。"
78
- },
79
- {
80
- "name": "FORMAT",
81
- "enCode": "FORMAT",
82
- "tip": "格式化文本",
83
- "example": "FORMAT(\"{0}年{1}月{2}日\",2024,12,1) = \"2024年12月1日\"",
84
- "usage": "FORMAT(模板,参数1,参数2,...)。"
85
- },
86
- {
87
- "name": "TOSTRING",
88
- "enCode": "TOSTRING",
89
- "tip": "转换为文本",
90
- "example": "TOSTRING(123) = \"123\"",
91
- "usage": "TOSTRING(值)。"
92
- }
93
- ]
@@ -1,13 +0,0 @@
1
- // 字符串函数
2
- import BaseFormula from '../base'
3
- import formula from './formula.json'
4
-
5
- export default class MathFormula extends BaseFormula {
6
- constructor () {
7
- super({
8
- name: '字符串函数',
9
- enCode: 'string',
10
- formula,
11
- })
12
- }
13
- }
package/src/index.js DELETED
@@ -1,5 +0,0 @@
1
- import FormulaEditor from './index.vue'
2
- import { calculate, formulaWatcher } from './core/calculate'
3
-
4
- export default FormulaEditor
5
- export { FormulaEditor, calculate, formulaWatcher }