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/package.json CHANGED
@@ -1,10 +1,17 @@
1
1
  {
2
2
  "name": "wy-editor",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "private": false,
5
+ "description": "公式配置",
6
+ "main": "dist/wy-editor.umd.min.js",
7
+ "module": "dist/wy-editor.common.js",
8
+ "files": [
9
+ "dist"
10
+ ],
5
11
  "scripts": {
6
12
  "dev": "vue-cli-service serve",
7
- "build": "vue-cli-service build"
13
+ "build": "vue-cli-service build --target lib --name wy-editor ./src/main.js",
14
+ "build:app": "vue-cli-service build"
8
15
  },
9
16
  "dependencies": {
10
17
  "core-js": "^3.8.3",
@@ -21,8 +28,6 @@
21
28
  "less-loader": "^12.2.0",
22
29
  "vue-template-compiler": "^2.6.14"
23
30
  },
24
- "description": "公式配置",
25
- "main": "babel.config.js",
26
31
  "author": "",
27
32
  "license": "ISC"
28
33
  }
package/.browserslistrc DELETED
@@ -1,3 +0,0 @@
1
- > 1%
2
- last 2 versions
3
- not dead
package/babel.config.js DELETED
@@ -1,5 +0,0 @@
1
- module.exports = {
2
- presets: [
3
- '@vue/cli-plugin-babel/preset'
4
- ]
5
- }
package/jsconfig.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es5",
4
- "module": "esnext",
5
- "baseUrl": "./",
6
- "moduleResolution": "node",
7
- "paths": {
8
- "@/*": [
9
- "src/*"
10
- ]
11
- },
12
- "lib": [
13
- "esnext",
14
- "dom",
15
- "dom.iterable",
16
- "scripthost"
17
- ]
18
- }
19
- }
Binary file
package/public/index.html DELETED
@@ -1,17 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
- <meta name="viewport" content="width=device-width,initial-scale=1.0">
7
- <link rel="icon" href="<%= BASE_URL %>favicon.ico">
8
- <title><%= htmlWebpackPlugin.options.title %></title>
9
- </head>
10
- <body>
11
- <noscript>
12
- <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
13
- </noscript>
14
- <div id="app"></div>
15
- <!-- built files will be auto injected -->
16
- </body>
17
- </html>
package/src/App.vue DELETED
@@ -1,127 +0,0 @@
1
- <template>
2
- <div id="app">
3
- <el-button type="text" @click="dialogVisible = true">配置公式</el-button>
4
- <!-- <el-form ref="form" :model="formData">
5
- <el-form-item label="名称">
6
- <el-input v-model="formData.name"></el-input>
7
- </el-form-item>
8
- <el-form-item label="描述">
9
- <el-input type="textarea" v-model="formData.desc"></el-input>
10
- </el-form-item>
11
- </el-form> -->
12
- <div>结果:{{ result }}</div>
13
- <el-dialog title="配置公式" :visible.sync="dialogVisible" width="800px">
14
- <editorIndex
15
- :formulaList="list"
16
- ref="formulaEditor"
17
- :formulaConf="formulaConf"
18
- :loading="true"
19
- :fieldList="fieldList"/>
20
- <!-- <FormulaEditor
21
- :formulaList="list"
22
- ref="formulaEditor"
23
- :formulaConf="formulaConf"
24
- :loading="true"
25
- :fieldList="fieldList"></FormulaEditor> -->
26
- <span slot="footer" class="dialog-footer">
27
- <el-button @click="onCancel">取 消</el-button>
28
- <el-button type="primary" @click="onConfirm">确 定</el-button>
29
- </span>
30
- </el-dialog>
31
- </div>
32
- </template>
33
- <script>
34
- import formulaObj from './formula'
35
- import editorIndex from './index'
36
- import { calculate, formulaWatcher, FormulaEditor } from 'vue-formula-editor'
37
-
38
- export default {
39
- name: 'HomeView',
40
- components: {
41
- FormulaEditor,
42
- editorIndex
43
- },
44
- data() {
45
- return {
46
- dialogVisible: true,
47
- formData: {
48
- name: '',
49
- desc: '',
50
- },
51
- result: 0,
52
- list: [],
53
- formulaConf: {},
54
- watchData: null,
55
- fieldList: [
56
- {
57
- fullName: '名称',
58
- value: 'string',
59
- enCode: 'name',
60
- },
61
- {
62
- fullName: '描述',
63
- value: 'string',
64
- enCode: 'desc',
65
- },
66
- {
67
- fullName: '名称1',
68
- value: 'string',
69
- enCode: 'name1',
70
- },
71
- {
72
- fullName: '描述1',
73
- value: 'string',
74
- enCode: 'desc1',
75
- },
76
- {
77
- fullName: '名称2',
78
- value: 'string',
79
- enCode: 'name2',
80
- },
81
- {
82
- fullName: '描述2',
83
- value: 'string',
84
- enCode: 'desc2',
85
- },
86
- ],
87
- }
88
- },
89
- computed: {
90
- nodes() {
91
- return this.list?.flatMap(o => o.formula) || []
92
- },
93
- },
94
- mounted() {
95
- this.list = formulaObj.map(ObjInstance => new ObjInstance())
96
- },
97
- methods: {
98
- onConfirm() {
99
- const data = this.$refs.formulaEditor.getData()
100
- this.result = data.text;
101
- this.dialogVisible = false
102
- return;
103
- this.formulaConf = data
104
- this.dialogVisible = false
105
-
106
- this.watchData?.()
107
- // 自动监听form表单的值
108
- this.watchData = formulaWatcher(
109
- this,
110
- { key: 'formData', value: this.formData },
111
- this.formulaConf,
112
- data => {
113
- this.result = data
114
- }
115
- )
116
- },
117
- onCancel() {
118
- this.dialogVisible = false
119
- },
120
- resetFormula() {
121
- this.$refs.formulaEditor.reset()
122
- },
123
- },
124
- }
125
- </script>
126
-
127
- <style></style>
Binary file
@@ -1,104 +0,0 @@
1
- <template>
2
- <el-scrollbar style="height: 240px;" class="field-variable">
3
-
4
- <div class="field-search">
5
- <el-input placeholder="搜索变量" prefix-icon="el-icon-search" v-model="searchVariable" clearable />
6
- </div>
7
- <div class="field-item" @click="$emit('fieldSelect', item)" v-for="item in filterFieldList" :key="item.enCode">
8
- <span>{{ item.fullName }}</span>
9
- <span :field-type="item.value" class="text-tag">
10
- {{ type[item.value] }}
11
- </span>
12
- </div>
13
-
14
- </el-scrollbar>
15
-
16
- </template>
17
-
18
- <script>
19
-
20
- export default {
21
- name: 'FieldVariable',
22
- props: {
23
- fieldList: {
24
- type: Array,
25
- default: () => [],
26
- },
27
- },
28
- components: {},
29
- data() {
30
- const type = {
31
- string: '字符串',
32
- number: '数字',
33
- array: '数组',
34
- }
35
- return {
36
- type,
37
- // 搜索值
38
- searchVariable: '',
39
- // 过滤后的变量
40
- filterFieldList: [],
41
- }
42
- },
43
- computed: {},
44
- watch: {
45
- searchVariable(val, old) {
46
- this.filterFieldList = this.fieldList.filter(({ fullName }) => fullName.includes(val))
47
- },
48
- },
49
- methods: {},
50
- async created() { },
51
- mounted() {
52
- this.filterFieldList = this.fieldList
53
- },
54
- }
55
- </script>
56
- <style lang="less" scoped>
57
- /deep/ .el-scrollbar__wrap {
58
- overflow-x: hidden;
59
- }
60
-
61
- .field-variable {
62
- max-width: 255px;
63
- border: 1px solid #eee;
64
- border-radius: 5px;
65
- margin-right: 10px;
66
- .field-search{
67
- width:95%;
68
- margin: 5px auto;
69
- }
70
- .field-item {
71
- display: flex;
72
- justify-content: space-between;
73
- align-items: center;
74
- cursor: pointer;
75
- padding: 8px;
76
- user-select: none;
77
-
78
- &:hover {
79
- background-color: #f0f1f4;
80
- }
81
-
82
- .text-tag {
83
- padding: 2px 6px;
84
- border-radius: 4px;
85
- color: #fff;
86
-
87
- &[field-type='string'] {
88
- color: #409eff;
89
- background-color: #ecf5ff;
90
- }
91
-
92
- &[field-type='number'] {
93
- color: #67c23a;
94
- background-color: #f0f9eb;
95
- }
96
-
97
- &[field-type='array'] {
98
- color: #e6a23c;
99
- background-color: #fdf6ec;
100
- }
101
- }
102
- }
103
- }
104
- </style>
@@ -1,132 +0,0 @@
1
- <template>
2
- <el-scrollbar style="height: 240px;" wrap-class="no-x-scrollbar" class="formula-list">
3
- <div class="field-search">
4
- <el-input placeholder='搜索函数' prefix-icon="el-icon-search" v-model="searchTreeVariable" clearable></el-input>
5
- </div>
6
- <div class="treeContainer" @mouseleave="leaveTree">
7
- <Tree :data="filterData" :default-expanded-keys="['frequentlyUse']" :props="props"
8
- :current-node-key="currentKeyNode.enCode" node-key="enCode" @node-click="nodeClick" highlight-current>
9
- <span class="info-container" @mouseenter="enterInfo(data)" slot-scope="{ data }">
10
- <span>{{ data.name }}</span>
11
- <span v-if="data.tip" class="tip">
12
- {{ data.tip }}
13
- </span>
14
- </span>
15
- </Tree>
16
- </div>
17
- </el-scrollbar>
18
-
19
- </template>
20
-
21
- <script>
22
- import 'element-ui/lib/theme-chalk/index.css'
23
- import { Tree } from 'element-ui'
24
-
25
- export default {
26
- name: 'FormulaList',
27
- components: { Tree },
28
- props: {
29
- nodes: {
30
- type: Array,
31
- default: () => [],
32
- },
33
- props: {
34
- type: Object,
35
- default: () => ({
36
- children: 'formula',
37
- label: 'name',
38
- }),
39
- },
40
- },
41
- data() {
42
- return {
43
- searchTreeVariable: "",
44
- // 选中的节点
45
- currentKeyNode: {},
46
- }
47
- },
48
- computed: {
49
- filterData() {
50
- if (!this.searchTreeVariable) {
51
- return this.nodes
52
- }
53
- return this.filterTreeData(this.nodes)
54
- },
55
- },
56
- watch: {},
57
- methods: {
58
- nodeClick(o) {
59
- const currentKeyNode = this.currentKeyNode
60
- // 目录情况
61
- if (o.formula) {
62
- if (currentKeyNode && currentKeyNode.enCode) {
63
- this.currentKeyNode = {}
64
- }
65
- return
66
- }
67
- this.currentKeyNode = o
68
- this.$emit('formulaClick', o)
69
- },
70
- filterTreeData(nodes) {
71
- // 找到nodes树中包含searchTreeVariable的节点但只有一层的结果
72
- return nodes.reduce((pre, cur) => {
73
- if (cur.name.toLowerCase().includes(this.searchTreeVariable)) {
74
- pre.push({ ...cur })
75
- }
76
- if (cur.formula) {
77
- pre.push(...this.filterTreeData(cur.formula))
78
- }
79
- return pre
80
- }, [])
81
- },
82
- enterInfo(data) {
83
- if (data.formula) return
84
- this.$emit('enterInfo', data)
85
- },
86
- leaveTree() {
87
- if (this.currentKeyNode && this.currentKeyNode.enCode) {
88
- this.$emit('enterInfo', this.currentKeyNode)
89
- }
90
- }
91
- },
92
- created() { },
93
- mounted() { },
94
- }
95
- </script>
96
- <style lang="less" scoped>
97
- /deep/ .el-scrollbar__wrap {
98
- overflow-x: hidden;
99
- }
100
- .no-x-scrollbar .el-scrollbar__wrap {
101
- overflow-x: hidden;
102
- }
103
- .field-search{
104
- width:95%;
105
- margin: 5px auto;
106
- }
107
-
108
- .formula-list {
109
- border-radius: 5px;
110
- border: 1px solid #eee;
111
- margin-right: 10px;
112
- .info-container {
113
- width: 100%;
114
- display: flex;
115
- flex-direction: column;
116
- }
117
-
118
- ::v-deep .el-tree-node__content {
119
- height: 100%;
120
- // margin-top: 6px;
121
- padding: 6px 0;
122
- user-select: none;
123
- }
124
-
125
- .tip {
126
- font-size: 12px;
127
- color: #999;
128
- margin-top: 1px;
129
- line-height: 1.2;
130
- }
131
- }
132
- </style>
@@ -1,90 +0,0 @@
1
- import functionCore from './functionCore'
2
-
3
- /**
4
- * 计算公式
5
- * @param {{text: string, marks: Array, value: Object}} params
6
- * @returns
7
- */
8
- function calculate(params) {
9
- const { text, marks = [], value = {} } = params
10
-
11
- if (!text) return new Error('非法公式')
12
- try {
13
- let str = text
14
- let offset = 0 // 偏移量
15
- marks.sort((a, b) => a.from.ch - b.from.ch)
16
- for (const mark of marks) {
17
- const { enCode, from, to, uuid } = mark
18
-
19
- let data = value[enCode] || value[uuid]
20
- // 子表情况
21
- if (enCode.indexOf('.') > -1) {
22
- const [key, subKey] = enCode.split('.')
23
- if (value[key]) data = value[key].map(o => o[subKey])
24
- }
25
- if (data !== undefined) {
26
- data = JSON.stringify(data)
27
- // 替换字符串的指定部分
28
- const startIndex = from.ch + offset
29
- const endIndex = to.ch + offset
30
-
31
- str = str.slice(0, startIndex) + data.toString() + str.slice(endIndex)
32
-
33
- // 更新偏移量
34
- offset += data.toString().length - (to.ch - from.ch)
35
- } else {
36
- return undefined
37
- }
38
- }
39
- const result = functionCore.executeFunction(str)
40
- return result
41
- } catch (e) {
42
- const errorTypes = {
43
- TypeError: () => '类型错误',
44
- RangeError: () => '范围错误',
45
- SyntaxError: () => '语法错误',
46
- ReferenceError: () => {
47
- const regex = /^(\w+)\s+is\s+not\s+defined$/
48
- const match = e.message.match(regex)
49
- return match ? `${match[1]} 未定义` : '未定义的变量'
50
- },
51
- }
52
- const errorType = errorTypes[e.constructor.name]
53
- const errorMessage = errorType?.() || `其他错误: ${e.message}`
54
- return {
55
- error: true,
56
- message: errorMessage,
57
- }
58
- }
59
- }
60
-
61
- /**
62
- * 动态监听并返回计算结果
63
- * @param {VueContentInstance} vm 当前Vue实例
64
- * @param {Object} formData 计算公式所需的数据
65
- * @param {Object} formulaConf 计算公式配置
66
- * @param {Function} fn 回调函数
67
- * @returns {Function} 取消监听函数
68
- */
69
- function formulaWatcher(vm, formData, formulaConf, fn) {
70
- const watchList = []
71
- const { key, value } = formData
72
-
73
- const toCalculate = () => {
74
- const data = calculate({
75
- value,
76
- marks: formulaConf.marks,
77
- text: formulaConf.text,
78
- })
79
- fn(data)
80
- }
81
- formulaConf.marks.forEach(mark => {
82
- const [preCode] = mark.enCode.split('.')
83
- const watchItem = vm.$watch(`${key}.${preCode}`, toCalculate)
84
- watchList.push(watchItem)
85
- })
86
- // 初始化计算
87
- toCalculate()
88
- return () => watchList.forEach(watchItem => watchItem())
89
- }
90
- export { calculate, formulaWatcher }
@@ -1,92 +0,0 @@
1
- import * as FormulaFunc from '@formulajs/formulajs'
2
-
3
- class FunctionCore {
4
- constructor() {
5
- Object.assign(FunctionCore.prototype, FormulaFunc)
6
-
7
- // 为了兼容不同的函数命名(如 Ceiling / CEILING / ceiling),对导入的函数创建大小写别名
8
- Object.keys(FormulaFunc).forEach(key => {
9
- const fn = FormulaFunc[key]
10
- if (typeof fn !== 'function') return
11
-
12
- const lower = key.toLowerCase()
13
- const upper = key.toUpperCase()
14
- const capitalized = key.charAt(0).toUpperCase() + key.slice(1).toLowerCase()
15
-
16
- if (!FunctionCore.prototype[lower]) FunctionCore.prototype[lower] = fn
17
- if (!FunctionCore.prototype[upper]) FunctionCore.prototype[upper] = fn
18
- if (!FunctionCore.prototype[capitalized]) FunctionCore.prototype[capitalized] = fn
19
- })
20
-
21
- // 若 formulajs 中没有一些常用的字符串函数(或命名差异),提供后备实现
22
- const fallbackStringFuncs = {
23
- TOLOWER: s => (s == null ? '' : String(s).toLowerCase()),
24
- TOUPPER: s => (s == null ? '' : String(s).toUpperCase()),
25
- CONCAT: (...args) => args.map(a => (a == null ? '' : String(a))).join(''),
26
- LENGTH: s => (s == null ? 0 : String(s).length),
27
- SUBSTRING: (s, start, len) => {
28
- const str = s == null ? '' : String(s)
29
- const st = Number(start) || 0
30
- if (len === undefined) return str.slice(st - 1)
31
- return str.substr(st - 1, Number(len) || 0)
32
- },
33
- TRIM: s => (s == null ? '' : String(s).trim()),
34
- REPLACE: (s, oldText, newText) => (s == null ? '' : String(s).split(oldText).join(newText)),
35
- INDEXOF: (s, sub) => {
36
- const idx = (s == null ? '' : String(s)).indexOf(sub == null ? '' : String(sub))
37
- return idx === -1 ? 0 : idx + 1
38
- },
39
- CONTAINS: (s, sub) => (s == null ? false : String(s).includes(sub == null ? '' : String(sub))),
40
- STARTSWITH: (s, pre) => (s == null ? false : String(s).startsWith(pre == null ? '' : String(pre))),
41
- ENDSWITH: (s, suf) => (s == null ? false : String(s).endsWith(suf == null ? '' : String(suf))),
42
- FORMAT: (template, ...args) => {
43
- const tpl = template == null ? '' : String(template)
44
- return tpl.replace(/\{(\d+)\}/g, (m, i) => (args[i] == null ? '' : String(args[i])))
45
- },
46
- TOSTRING: v => (v == null ? '' : String(v)),
47
- }
48
-
49
- Object.keys(fallbackStringFuncs).forEach(k => {
50
- if (!FunctionCore.prototype[k]) FunctionCore.prototype[k] = fallbackStringFuncs[k]
51
- })
52
-
53
- // 后备数学函数(避免 Truncate 等未定义)
54
- const fallbackMathFuncs = {
55
- Truncate: n => {
56
- if (n == null) return 0
57
- const num = Number(n)
58
- if (Number.isNaN(num)) return 0
59
- if (typeof Math.trunc === 'function') return Math.trunc(num)
60
- return num < 0 ? Math.ceil(num) : Math.floor(num)
61
- },
62
- ACos: n => {
63
- if (n == null) return 0
64
- const num = Number(n)
65
- if (Number.isNaN(num)) return 0
66
- return Math.acos(num)
67
- },
68
- Pow: (base, exp) => {
69
- const b = Number(base)
70
- const e = Number(exp)
71
- if (Number.isNaN(b) || Number.isNaN(e)) return 0
72
- return Math.pow(b, e)
73
- },
74
- }
75
-
76
- Object.keys(fallbackMathFuncs).forEach(k => {
77
- if (!FunctionCore.prototype[k]) FunctionCore.prototype[k] = fallbackMathFuncs[k]
78
- })
79
- }
80
-
81
- executeFunction(str) { // 执行函数
82
- const fn = new Function(
83
- 'with(this) { return ' + str + '; }' // 使用 `with` 来确保从当前实例中查找函数
84
- ).bind(this)
85
-
86
- return fn()
87
- }
88
- }
89
- // 单例对象,保证全局只有一个实例
90
- const functionCore = new FunctionCore()
91
-
92
- export default functionCore