vue更新3.5,以及mime打更新
This commit is contained in:
271
cdTMP/package-lock.json
generated
271
cdTMP/package-lock.json
generated
@@ -25,7 +25,7 @@
|
|||||||
"postcss-import": "^16.1.0",
|
"postcss-import": "^16.1.0",
|
||||||
"qs": "^6.13.0",
|
"qs": "^6.13.0",
|
||||||
"tinymce": "^7.3.0",
|
"tinymce": "^7.3.0",
|
||||||
"vue": "3.4.38",
|
"vue": "^3.5.2",
|
||||||
"vue-clipboard3": "^2.0.0",
|
"vue-clipboard3": "^2.0.0",
|
||||||
"vue-color-kit": "^1.0.6",
|
"vue-color-kit": "^1.0.6",
|
||||||
"vue-echarts": "^7.0.3",
|
"vue-echarts": "^7.0.3",
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^22.5.3",
|
"@types/node": "^22.5.4",
|
||||||
"@types/nprogress": "^0.2.3",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@types/qs": "^6.9.15",
|
"@types/qs": "^6.9.15",
|
||||||
"@vitejs/plugin-vue": "^5.1.3",
|
"@vitejs/plugin-vue": "^5.1.3",
|
||||||
@@ -42,17 +42,17 @@
|
|||||||
"@vue/babel-plugin-jsx": "^1.1.1",
|
"@vue/babel-plugin-jsx": "^1.1.1",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"browserslist": "^4.23.0",
|
"browserslist": "^4.23.0",
|
||||||
"caniuse-lite": "^1.0.30001655",
|
"caniuse-lite": "^1.0.30001657",
|
||||||
"eslint": "^9.9.1",
|
"eslint": "^9.9.1",
|
||||||
"eslint-plugin-vue": "^9.28.0",
|
"eslint-plugin-vue": "^9.28.0",
|
||||||
"less": "^4.2.0",
|
"less": "^4.2.0",
|
||||||
"less-loader": "^12.2.0",
|
"less-loader": "^12.2.0",
|
||||||
"postcss": "^8.4.44",
|
"postcss": "^8.4.45",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"rollup-plugin-visualizer": "^5.12.0",
|
"rollup-plugin-visualizer": "^5.12.0",
|
||||||
"tailwindcss": "^3.4.10",
|
"tailwindcss": "^3.4.10",
|
||||||
"typescript": "^5.5.3",
|
"typescript": "^5.5.3",
|
||||||
"vite": "5.4.2"
|
"vite": "^5.4.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@alloc/quick-lru": {
|
"node_modules/@alloc/quick-lru": {
|
||||||
@@ -1421,9 +1421,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "22.5.3",
|
"version": "22.5.4",
|
||||||
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.5.3.tgz",
|
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.5.4.tgz",
|
||||||
"integrity": "sha512-njripolh85IA9SQGTAqbmnNZTdxv7X/4OYGPz8tgy5JDr8MP+uDBa921GpYEoDDnwm0Hmn5ZPeJgiiSTPoOzkQ==",
|
"integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1556,42 +1556,39 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-core": {
|
"node_modules/@vue/compiler-core": {
|
||||||
"version": "3.5.0",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.2.tgz",
|
||||||
"integrity": "sha512-ja7cpqAOfw4tyFAxgBz70Z42miNDeaqTxExTsnXDLomRpqfyCgyvZvFp482fmsElpfvsoMJUsvzULhvxUTW6Iw==",
|
"integrity": "sha512-1aP7FL2GkqfcskHWGg3lfWQpJnrmewKc+rNJ/hq9WNaAw4BEyJ5QbNChnqmbw+tJ409zdy1XWmUeXXMrCKJcQQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.25.3",
|
"@babel/parser": "^7.25.3",
|
||||||
"@vue/shared": "3.5.0",
|
"@vue/shared": "3.5.2",
|
||||||
"entities": "^4.5.0",
|
"entities": "^4.5.0",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"source-map-js": "^1.2.0"
|
"source-map-js": "^1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-dom": {
|
"node_modules/@vue/compiler-dom": {
|
||||||
"version": "3.5.0",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.2.tgz",
|
||||||
"integrity": "sha512-xYjUybWZXl+1R/toDy815i4PbeehL2hThiSGkcpmIOCy2HoYyeeC/gAWK/Y/xsoK+GSw198/T5O31bYuQx5uvQ==",
|
"integrity": "sha512-QY4DpT8ZIUyu/ZA5gErpSEDocGNEbHmpkZIC/d5jbp/rUF0iOJNigAy3HCCKc0PMMhDlrcysO3ufQ6Ab4MpEcQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-core": "3.5.0",
|
"@vue/compiler-core": "3.5.2",
|
||||||
"@vue/shared": "3.5.0"
|
"@vue/shared": "3.5.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-sfc": {
|
"node_modules/@vue/compiler-sfc": {
|
||||||
"version": "3.5.0",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.2.tgz",
|
||||||
"integrity": "sha512-B9DgLtrqok2GLuaFjLlSL15ZG3ZDBiitUH1ecex9guh/ZcA5MCdwuVE6nsfQxktuZY/QY0awJ35/ripIviCQTQ==",
|
"integrity": "sha512-vErEtybSU290LbMW+ChYllI9tNJEdTW1oU+8cZWINZyjlWeTSa9YqDl4/pZJSnozOI+HmcaC1Vz2eFKmXNSXZA==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.25.3",
|
"@babel/parser": "^7.25.3",
|
||||||
"@vue/compiler-core": "3.5.0",
|
"@vue/compiler-core": "3.5.2",
|
||||||
"@vue/compiler-dom": "3.5.0",
|
"@vue/compiler-dom": "3.5.2",
|
||||||
"@vue/compiler-ssr": "3.5.0",
|
"@vue/compiler-ssr": "3.5.2",
|
||||||
"@vue/shared": "3.5.0",
|
"@vue/shared": "3.5.2",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"magic-string": "^0.30.11",
|
"magic-string": "^0.30.11",
|
||||||
"postcss": "^8.4.44",
|
"postcss": "^8.4.44",
|
||||||
@@ -1599,14 +1596,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr": {
|
"node_modules/@vue/compiler-ssr": {
|
||||||
"version": "3.5.0",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.2.tgz",
|
||||||
"integrity": "sha512-E263QZmA1dqRd7c3u/sWTLRMpQOT0aZ8av/L9SoD/v/BVMZaWFHPUUBswS+bzrfvG2suJF8vSLKx6k6ba5SUdA==",
|
"integrity": "sha512-vMtA4tQK/AM3UAYJsmouQzQpgG+h9TKiD5BV+Zt+ZyAMdicxzSEEFGWf/CykRnDpqj9fMfIHPhOezJVNxiXe2A==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.5.0",
|
"@vue/compiler-dom": "3.5.2",
|
||||||
"@vue/shared": "3.5.0"
|
"@vue/shared": "3.5.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/devtools-api": {
|
"node_modules/@vue/devtools-api": {
|
||||||
@@ -1616,122 +1612,53 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vue/reactivity": {
|
"node_modules/@vue/reactivity": {
|
||||||
"version": "3.5.0",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.2.tgz",
|
||||||
"integrity": "sha512-Ew3F5riP3B3ZDGjD3ZKb9uZylTTPSqt8hAf4sGbvbjrjDjrFb3Jm15Tk1/w7WwTE5GbQ2Qhwxx1moc9hr8A/OQ==",
|
"integrity": "sha512-lJwWL5bNht+2vIwU/+lnGdH+FKFxzz6z8WkoIJityPLiasWU+HDUvEsC7gm3JFwbTf7Kk+Nr9kJMaPy0HXwwxQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/shared": "3.5.0"
|
"@vue/shared": "3.5.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-core": {
|
"node_modules/@vue/runtime-core": {
|
||||||
"version": "3.5.0",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.2.tgz",
|
||||||
"integrity": "sha512-mQyW0F9FaNRdt8ghkAs+BMG3iQ7LGgWKOpkzUzR5AI5swPNydHGL5hvVTqFaeMzwecF1g0c86H4yFQsSxJhH1w==",
|
"integrity": "sha512-oU+i9sJjGEMfEhlrJ7SZv7CdSIgUNyBHnWHa0SqU2RF48V3/ATajzpWq1/DkiVJ1mtx+cQFAMKs8s/3cB3YlLQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.5.0",
|
"@vue/reactivity": "3.5.2",
|
||||||
"@vue/shared": "3.5.0"
|
"@vue/shared": "3.5.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-dom": {
|
"node_modules/@vue/runtime-dom": {
|
||||||
"version": "3.4.38",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.4.38.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.2.tgz",
|
||||||
"integrity": "sha512-afZzmUreU7vKwKsV17H1NDThEEmdYI+GCAK/KY1U957Ig2NATPVjCROv61R19fjZNzMmiU03n79OMnXyJVN0UA==",
|
"integrity": "sha512-2qvysn+oR0QnFKaWZxQ90iVpWAK/WPpYmODHCv24IDXjsBrdHbjLBj9s6YBdPaMuQhs0LNsmhsgZYZBkszLg6g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.4.38",
|
"@vue/reactivity": "3.5.2",
|
||||||
"@vue/runtime-core": "3.4.38",
|
"@vue/runtime-core": "3.5.2",
|
||||||
"@vue/shared": "3.4.38",
|
"@vue/shared": "3.5.2",
|
||||||
"csstype": "^3.1.3"
|
"csstype": "^3.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/runtime-dom/node_modules/@vue/reactivity": {
|
|
||||||
"version": "3.4.38",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.4.38.tgz",
|
|
||||||
"integrity": "sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@vue/shared": "3.4.38"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@vue/runtime-dom/node_modules/@vue/runtime-core": {
|
|
||||||
"version": "3.4.38",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.4.38.tgz",
|
|
||||||
"integrity": "sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@vue/reactivity": "3.4.38",
|
|
||||||
"@vue/shared": "3.4.38"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@vue/runtime-dom/node_modules/@vue/shared": {
|
|
||||||
"version": "3.4.38",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.38.tgz",
|
|
||||||
"integrity": "sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@vue/server-renderer": {
|
"node_modules/@vue/server-renderer": {
|
||||||
"version": "3.4.38",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.4.38.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.2.tgz",
|
||||||
"integrity": "sha512-NggOTr82FbPEkkUvBm4fTGcwUY8UuTsnWC/L2YZBmvaQ4C4Jl/Ao4HHTB+l7WnFCt5M/dN3l0XLuyjzswGYVCA==",
|
"integrity": "sha512-3POhYCA8KfbmuDuUiNbMXnpdh9pwE4SvAqo7VvACjklLkf3AaMkY3TvV7APeEa/WQezrnL+E4X2ASpJsKeS4cQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-ssr": "3.4.38",
|
"@vue/compiler-ssr": "3.5.2",
|
||||||
"@vue/shared": "3.4.38"
|
"@vue/shared": "3.5.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": "3.4.38"
|
"vue": "3.5.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vue/server-renderer/node_modules/@vue/compiler-core": {
|
|
||||||
"version": "3.4.38",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.38.tgz",
|
|
||||||
"integrity": "sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/parser": "^7.24.7",
|
|
||||||
"@vue/shared": "3.4.38",
|
|
||||||
"entities": "^4.5.0",
|
|
||||||
"estree-walker": "^2.0.2",
|
|
||||||
"source-map-js": "^1.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@vue/server-renderer/node_modules/@vue/compiler-dom": {
|
|
||||||
"version": "3.4.38",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.38.tgz",
|
|
||||||
"integrity": "sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@vue/compiler-core": "3.4.38",
|
|
||||||
"@vue/shared": "3.4.38"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@vue/server-renderer/node_modules/@vue/compiler-ssr": {
|
|
||||||
"version": "3.4.38",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.38.tgz",
|
|
||||||
"integrity": "sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@vue/compiler-dom": "3.4.38",
|
|
||||||
"@vue/shared": "3.4.38"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@vue/server-renderer/node_modules/@vue/shared": {
|
|
||||||
"version": "3.4.38",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.38.tgz",
|
|
||||||
"integrity": "sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@vue/shared": {
|
"node_modules/@vue/shared": {
|
||||||
"version": "3.5.0",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.2.tgz",
|
||||||
"integrity": "sha512-m9IgiteBpCkFaMNwCOBkFksA7z8QiKc30ooRuoXWUFRDu0mGyNPlFHmbncF0/Kra1RlX8QrmBbRaIxVvikaR0Q==",
|
"integrity": "sha512-Ce89WNFBzcDca/AgFTxgX4/K4iAyF7oFIp8Z5aBbFBNbtpwnQr+5pZOoHndxnjE2h+YFcipVMzs9UL11XB6dwA==",
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vueuse/core": {
|
"node_modules/@vueuse/core": {
|
||||||
@@ -2339,9 +2266,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001655",
|
"version": "1.0.30001657",
|
||||||
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz",
|
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001657.tgz",
|
||||||
"integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==",
|
"integrity": "sha512-DPbJAlP8/BAXy3IgiWmZKItubb3TYGP0WscQQlVGIfT4s/YlFYVuJgyOsQNP7rJRChx/qdMeLJQJP0Sgg2yjNA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -4535,9 +4462,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.4.44",
|
"version": "8.4.45",
|
||||||
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.44.tgz",
|
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.45.tgz",
|
||||||
"integrity": "sha512-Aweb9unOEpQ3ezu4Q00DPvvM2ZTUitJdNKeP/+uQgr1IBIqu574IaZoURId7BKtWMREwzKa9OgzPzezWGPWFQw==",
|
"integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -5502,14 +5429,14 @@
|
|||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "5.4.2",
|
"version": "5.4.3",
|
||||||
"resolved": "https://registry.npmmirror.com/vite/-/vite-5.4.2.tgz",
|
"resolved": "https://registry.npmmirror.com/vite/-/vite-5.4.3.tgz",
|
||||||
"integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==",
|
"integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.21.3",
|
"esbuild": "^0.21.3",
|
||||||
"postcss": "^8.4.41",
|
"postcss": "^8.4.43",
|
||||||
"rollup": "^4.20.0"
|
"rollup": "^4.20.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -5562,16 +5489,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vue": {
|
"node_modules/vue": {
|
||||||
"version": "3.4.38",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.4.38.tgz",
|
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.2.tgz",
|
||||||
"integrity": "sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==",
|
"integrity": "sha512-w1YB4lAwC9ByH6AnFY0JvZF+y70Usul9jDfKIKtM5xA97q/JPS5R7mqq0fhA6D2PQxYPZdgb5jzFKLyOga5pnw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.4.38",
|
"@vue/compiler-dom": "3.5.2",
|
||||||
"@vue/compiler-sfc": "3.4.38",
|
"@vue/compiler-sfc": "3.5.2",
|
||||||
"@vue/runtime-dom": "3.4.38",
|
"@vue/runtime-dom": "3.5.2",
|
||||||
"@vue/server-renderer": "3.4.38",
|
"@vue/server-renderer": "3.5.2",
|
||||||
"@vue/shared": "3.4.38"
|
"@vue/shared": "3.5.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "*"
|
"typescript": "*"
|
||||||
@@ -5691,62 +5618,6 @@
|
|||||||
"vue": "^3.2.0"
|
"vue": "^3.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vue/node_modules/@vue/compiler-core": {
|
|
||||||
"version": "3.4.38",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.4.38.tgz",
|
|
||||||
"integrity": "sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/parser": "^7.24.7",
|
|
||||||
"@vue/shared": "3.4.38",
|
|
||||||
"entities": "^4.5.0",
|
|
||||||
"estree-walker": "^2.0.2",
|
|
||||||
"source-map-js": "^1.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vue/node_modules/@vue/compiler-dom": {
|
|
||||||
"version": "3.4.38",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.4.38.tgz",
|
|
||||||
"integrity": "sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@vue/compiler-core": "3.4.38",
|
|
||||||
"@vue/shared": "3.4.38"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vue/node_modules/@vue/compiler-sfc": {
|
|
||||||
"version": "3.4.38",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.4.38.tgz",
|
|
||||||
"integrity": "sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/parser": "^7.24.7",
|
|
||||||
"@vue/compiler-core": "3.4.38",
|
|
||||||
"@vue/compiler-dom": "3.4.38",
|
|
||||||
"@vue/compiler-ssr": "3.4.38",
|
|
||||||
"@vue/shared": "3.4.38",
|
|
||||||
"estree-walker": "^2.0.2",
|
|
||||||
"magic-string": "^0.30.10",
|
|
||||||
"postcss": "^8.4.40",
|
|
||||||
"source-map-js": "^1.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vue/node_modules/@vue/compiler-ssr": {
|
|
||||||
"version": "3.4.38",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.4.38.tgz",
|
|
||||||
"integrity": "sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@vue/compiler-dom": "3.4.38",
|
|
||||||
"@vue/shared": "3.4.38"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vue/node_modules/@vue/shared": {
|
|
||||||
"version": "3.4.38",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.4.38.tgz",
|
|
||||||
"integrity": "sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/vuedraggable": {
|
"node_modules/vuedraggable": {
|
||||||
"version": "2.24.3",
|
"version": "2.24.3",
|
||||||
"resolved": "https://registry.npmmirror.com/vuedraggable/-/vuedraggable-2.24.3.tgz",
|
"resolved": "https://registry.npmmirror.com/vuedraggable/-/vuedraggable-2.24.3.tgz",
|
||||||
|
|||||||
@@ -28,16 +28,16 @@
|
|||||||
"postcss-import": "^16.1.0",
|
"postcss-import": "^16.1.0",
|
||||||
"qs": "^6.13.0",
|
"qs": "^6.13.0",
|
||||||
"tinymce": "^7.3.0",
|
"tinymce": "^7.3.0",
|
||||||
|
"vue": "^3.5.2",
|
||||||
"vue-clipboard3": "^2.0.0",
|
"vue-clipboard3": "^2.0.0",
|
||||||
"vue-color-kit": "^1.0.6",
|
"vue-color-kit": "^1.0.6",
|
||||||
"vue-echarts": "^7.0.3",
|
"vue-echarts": "^7.0.3",
|
||||||
"vue-router": "^4.4.3",
|
"vue-router": "^4.4.3",
|
||||||
"vuedraggable": "^2.24.3",
|
"vuedraggable": "^2.24.3"
|
||||||
"vue": "3.4.38"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^22.5.3",
|
"@types/node": "^22.5.4",
|
||||||
"@types/nprogress": "^0.2.3",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@types/qs": "^6.9.15",
|
"@types/qs": "^6.9.15",
|
||||||
"@vitejs/plugin-vue": "^5.1.3",
|
"@vitejs/plugin-vue": "^5.1.3",
|
||||||
@@ -45,16 +45,16 @@
|
|||||||
"@vue/babel-plugin-jsx": "^1.1.1",
|
"@vue/babel-plugin-jsx": "^1.1.1",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"browserslist": "^4.23.0",
|
"browserslist": "^4.23.0",
|
||||||
"caniuse-lite": "^1.0.30001655",
|
"caniuse-lite": "^1.0.30001657",
|
||||||
"eslint": "^9.9.1",
|
"eslint": "^9.9.1",
|
||||||
"eslint-plugin-vue": "^9.28.0",
|
"eslint-plugin-vue": "^9.28.0",
|
||||||
"less": "^4.2.0",
|
"less": "^4.2.0",
|
||||||
"less-loader": "^12.2.0",
|
"less-loader": "^12.2.0",
|
||||||
"postcss": "^8.4.44",
|
"postcss": "^8.4.45",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"rollup-plugin-visualizer": "^5.12.0",
|
"rollup-plugin-visualizer": "^5.12.0",
|
||||||
"tailwindcss": "^3.4.10",
|
"tailwindcss": "^3.4.10",
|
||||||
"typescript": "^5.5.3",
|
"typescript": "^5.5.3",
|
||||||
"vite": "5.4.2"
|
"vite": "^5.4.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 1024 1024" class="icon" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
|
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<v-charts v-if="renderChart" :option="options" :autoresize="autoresize" :style="{ width, height }" />
|
<v-charts v-if="renderChart" :option="options" :autoresize="autoresize" :style="{ width, height }" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-cascader
|
<a-cascader
|
||||||
v-if="props.type === 'cascader'"
|
v-if="props.type === 'cascader'"
|
||||||
@@ -70,7 +74,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import jsonData from "./lib/city.json"
|
import jsonData from "./lib/city.json"
|
||||||
import { ref, watch } from "vue"
|
import { ref, watch } from "vue"
|
||||||
import { isObject } from "lodash"
|
import { isObject } from "lodash-es"
|
||||||
|
|
||||||
const val = ref()
|
const val = ref()
|
||||||
const selectData = ref({ province: [], city: [], area: [] })
|
const selectData = ref({ province: [], city: [], area: [] })
|
||||||
@@ -139,7 +143,7 @@ val.value = props.modelValue
|
|||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
(vl) => () => {
|
(vl) => {
|
||||||
val.value = vl
|
val.value = vl
|
||||||
setSelectData()
|
setSelectData()
|
||||||
},
|
},
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -22,19 +22,28 @@
|
|||||||
</a-input-group>
|
</a-input-group>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, reactive } from "vue"
|
import { reactive, computed } from "vue"
|
||||||
import { ColorPicker } from "vue-color-kit"
|
import { ColorPicker } from "vue-color-kit"
|
||||||
import "vue-color-kit/dist/vue-color-kit.css"
|
import "vue-color-kit/dist/vue-color-kit.css"
|
||||||
import { generate, getRgbStr } from "@arco-design/color"
|
|
||||||
import useClipboard from "vue-clipboard3"
|
import useClipboard from "vue-clipboard3"
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
|
|
||||||
const val = ref()
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: String,
|
modelValue: String,
|
||||||
placeholder: { type: String, default: "请选择颜色" }
|
placeholder: { type: String, default: "请选择颜色" }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:modelValue"])
|
||||||
|
|
||||||
|
const val = computed({
|
||||||
|
get() {
|
||||||
|
return props.modelValue
|
||||||
|
},
|
||||||
|
set(newVal) {
|
||||||
|
emit("update:modelValue", newVal)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const selectColor = (color) => {
|
const selectColor = (color) => {
|
||||||
val.value = color.hex
|
val.value = color.hex
|
||||||
}
|
}
|
||||||
@@ -66,11 +75,4 @@ const defaultColorList = reactive([
|
|||||||
"#86909c",
|
"#86909c",
|
||||||
"#6d4c41"
|
"#6d4c41"
|
||||||
])
|
])
|
||||||
|
|
||||||
const emit = defineEmits(["update:modelValue"])
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => val.value,
|
|
||||||
(vl) => emit("update:modelValue", vl)
|
|
||||||
)
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<template v-for="row in props.columns" :key="row[options.pk]">
|
<template v-for="row in props.columns" :key="row[options.pk]">
|
||||||
<template v-if="!row.hide">
|
<template v-if="isFunction(row.hide) ? row.hide() : !row.hide">
|
||||||
<a-table-column
|
<a-table-column
|
||||||
:title="row.title"
|
:title="row.title"
|
||||||
:width="row.width"
|
:width="row.width"
|
||||||
|
:min-width="row.minWidth"
|
||||||
:ellipsis="row.ellipsis ?? true"
|
:ellipsis="row.ellipsis ?? true"
|
||||||
:filterable="row.filterable"
|
:filterable="row.filterable"
|
||||||
:cell-class="row.cellClass"
|
:cell-class="row.cellClass"
|
||||||
@@ -38,6 +39,7 @@
|
|||||||
:title="row.title"
|
:title="row.title"
|
||||||
:data-index="row.dataIndex"
|
:data-index="row.dataIndex"
|
||||||
:width="row.width"
|
:width="row.width"
|
||||||
|
:min-width="row.minWidth"
|
||||||
:ellipsis="row.ellipsis ?? true"
|
:ellipsis="row.ellipsis ?? true"
|
||||||
:filterable="row.filterable"
|
:filterable="row.filterable"
|
||||||
:cell-class="row.cellClass"
|
:cell-class="row.cellClass"
|
||||||
@@ -48,12 +50,15 @@
|
|||||||
:header-cell-style="row.headerCellStyle"
|
:header-cell-style="row.headerCellStyle"
|
||||||
:body-cell-style="row.bodyCellStyle"
|
:body-cell-style="row.bodyCellStyle"
|
||||||
:summary-cell-style="row.summaryCellStyle"
|
:summary-cell-style="row.summaryCellStyle"
|
||||||
:tooltip="row.dataIndex === '__operation' ? false : row.tooltip ?? true"
|
:tooltip="row.dataIndex === '__operation' ? false : (row.tooltip ?? true)"
|
||||||
:align="row.align || 'left'"
|
:align="row.align || 'left'"
|
||||||
:fixed="row.fixed"
|
:fixed="row.fixed"
|
||||||
:sortable="row.sortable"
|
:sortable="row.sortable"
|
||||||
v-else
|
v-else
|
||||||
>
|
>
|
||||||
|
<template #title>
|
||||||
|
<slot :name="`tableTitle-${row.dataIndex}`" v-bind="{ column: row }">{{ row.title }}</slot>
|
||||||
|
</template>
|
||||||
<template #cell="{ record, column, rowIndex }">
|
<template #cell="{ record, column, rowIndex }">
|
||||||
<!-- 操作栏 -->
|
<!-- 操作栏 -->
|
||||||
<template v-if="row.dataIndex === '__operation'">
|
<template v-if="row.dataIndex === '__operation'">
|
||||||
@@ -61,22 +66,41 @@
|
|||||||
<a-space size="mini">
|
<a-space size="mini">
|
||||||
<slot name="operationBeforeExtend" v-bind="{ record, column, rowIndex }"></slot>
|
<slot name="operationBeforeExtend" v-bind="{ record, column, rowIndex }"></slot>
|
||||||
<slot name="operationCell" v-bind="{ record, column, rowIndex }">
|
<slot name="operationCell" v-bind="{ record, column, rowIndex }">
|
||||||
<!-- <a-link
|
<a-link
|
||||||
v-if="
|
v-if="
|
||||||
options.see.show
|
(isFunction(options.see.show)
|
||||||
&& ($common.auth(options.see.auth || [])
|
? options.see.show(record)
|
||||||
|| (options.see.role || []))
|
: options.see.show) && !props.isRecovery
|
||||||
"
|
"
|
||||||
type="primary"
|
v-auth="options.see.auth || []"
|
||||||
><icon-eye /> {{ options.see.text || '查看' }}</a-link> -->
|
v-role="options.see.role || []"
|
||||||
|
type="primary"
|
||||||
|
:status="options.see.status || 'success'"
|
||||||
|
:style="{ color: options.see.color || '' }"
|
||||||
|
:disabled="
|
||||||
|
isFunction(options.see.disabled)
|
||||||
|
? options.see.disabled(record)
|
||||||
|
: options.see.disabled
|
||||||
|
"
|
||||||
|
@click="seeAction(record)"
|
||||||
|
><icon-eye /> {{ options.see.text || "查看" }}</a-link
|
||||||
|
>
|
||||||
<a-link
|
<a-link
|
||||||
v-if="
|
v-if="
|
||||||
(isFunction(options.edit.show)
|
(isFunction(options.edit.show)
|
||||||
? options.edit.show(record)
|
? options.edit.show(record)
|
||||||
: options.edit.show) && !props.isRecovery
|
: options.edit.show) && !props.isRecovery
|
||||||
"
|
"
|
||||||
|
v-auth="options.edit.auth || []"
|
||||||
|
v-role="options.edit.role || []"
|
||||||
type="primary"
|
type="primary"
|
||||||
|
:status="options.edit.status || 'normal'"
|
||||||
|
:style="{ color: options.edit.color || '' }"
|
||||||
|
:disabled="
|
||||||
|
isFunction(options.edit.disabled)
|
||||||
|
? options.edit.disabled(record)
|
||||||
|
: options.edit.disabled
|
||||||
|
"
|
||||||
@click="editAction(record)"
|
@click="editAction(record)"
|
||||||
>
|
>
|
||||||
<icon-edit /> {{ options.edit.text || "编辑" }}
|
<icon-edit /> {{ options.edit.text || "编辑" }}
|
||||||
@@ -91,6 +115,8 @@
|
|||||||
? options.recovery.show(record)
|
? options.recovery.show(record)
|
||||||
: options.recovery.show) && props.isRecovery
|
: options.recovery.show) && props.isRecovery
|
||||||
"
|
"
|
||||||
|
v-auth="options.recovery.auth || []"
|
||||||
|
v-role="options.recovery.role || []"
|
||||||
>
|
>
|
||||||
<a-link type="primary"
|
<a-link type="primary"
|
||||||
><icon-undo /> {{ options.recovery.text || "恢复" }}
|
><icon-undo /> {{ options.recovery.text || "恢复" }}
|
||||||
@@ -107,7 +133,18 @@
|
|||||||
: options.delete.show
|
: options.delete.show
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<a-link type="primary">
|
<a-link
|
||||||
|
type="primary"
|
||||||
|
:status="options.delete.status || 'danger'"
|
||||||
|
:style="{ color: options.delete.color || '' }"
|
||||||
|
v-auth="options.delete.auth || []"
|
||||||
|
v-role="options.delete.role || []"
|
||||||
|
:disabled="
|
||||||
|
isFunction(options.delete.disabled)
|
||||||
|
? options.delete.disabled(record)
|
||||||
|
: options.delete.disabled
|
||||||
|
"
|
||||||
|
>
|
||||||
<icon-delete />
|
<icon-delete />
|
||||||
{{
|
{{
|
||||||
props.isRecovery
|
props.isRecovery
|
||||||
@@ -131,28 +168,66 @@
|
|||||||
</template>
|
</template>
|
||||||
<slot :name="row.dataIndex" v-bind="{ record, column, rowIndex }" v-else>
|
<slot :name="row.dataIndex" v-bind="{ record, column, rowIndex }" v-else>
|
||||||
<template v-if="row.dataIndex === '__index'">{{ getIndex(rowIndex) }}</template>
|
<template v-if="row.dataIndex === '__index'">{{ getIndex(rowIndex) }}</template>
|
||||||
|
<span :class="['relative', row?.quickEdit && allowQuickEdit(row.formType) ? 'flex' : '']">
|
||||||
<template v-if="row.dict && row.dict.translation">
|
<template v-if="row.isEdit">
|
||||||
<template v-if="isArray(get(record, row.dataIndex))">
|
<a-form>
|
||||||
<a-tag v-for="item in get(record, row.dataIndex)" class="ml-1">{{
|
<a-button-group class="flex">
|
||||||
getDataIndex(row, item)
|
<a-input
|
||||||
}}</a-tag>
|
v-if="row?.formType === undefined || row.formType === 'input'"
|
||||||
|
v-bind="row"
|
||||||
|
v-model="record[row.dataIndex]"
|
||||||
|
/>
|
||||||
|
<a-input-number
|
||||||
|
v-if="row.formType === 'input-number'"
|
||||||
|
v-bind="row"
|
||||||
|
v-model="record[row.dataIndex]"
|
||||||
|
/>
|
||||||
|
<a-select
|
||||||
|
v-if="['select', 'radio'].includes(row.formType)"
|
||||||
|
v-bind="row"
|
||||||
|
v-model="record[row.dataIndex]"
|
||||||
|
:options="dicts[row.dataIndex]"
|
||||||
|
/>
|
||||||
|
<a-link
|
||||||
|
class="block"
|
||||||
|
v-if="row?.quickEdit && allowQuickEdit(row.formType) && row.isEdit === true"
|
||||||
|
@click="updateQuickEditData(row, record)"
|
||||||
|
>
|
||||||
|
<icon-check />
|
||||||
|
</a-link>
|
||||||
|
</a-button-group>
|
||||||
|
</a-form>
|
||||||
</template>
|
</template>
|
||||||
<a-tag v-else-if="row.dict.tagColors" :color="getTagColor(row, record)">
|
<template v-else-if="row.dict && row.dict.translation">
|
||||||
{{ getDataIndex(row, record) }}
|
<template v-if="isArray(get(record, row.dataIndex))">
|
||||||
</a-tag>
|
<a-tag v-for="item in get(record, row.dataIndex)" class="ml-1">{{
|
||||||
<a-tag v-else-if="row.dict.tagColor" :color="row.dict.tagColor">{{
|
getDataIndex(row, item)
|
||||||
getDataIndex(row, record)
|
}}</a-tag>
|
||||||
}}</a-tag>
|
</template>
|
||||||
<span v-else>{{ getDataIndex(row, record) }}</span>
|
<a-tag v-else-if="row.dict.tagColors" :color="getTagColor(row, record)">
|
||||||
</template>
|
{{ getDataIndex(row, record) }}
|
||||||
<template v-else-if="row.dataIndex && row.dataIndex.indexOf('.') !== -1">
|
</a-tag>
|
||||||
{{ get(record, row.dataIndex) }}
|
<a-tag v-else-if="row.dict.tagColor" :color="row.dict.tagColor">{{
|
||||||
</template>
|
getDataIndex(row, record)
|
||||||
<template v-else-if="row.formType === 'upload'">
|
}}</a-tag>
|
||||||
<a-link @click="imageSee(row, record, row.dataIndex)"><icon-image /> 查看图片</a-link>
|
<span v-else>{{ getDataIndex(row, record) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>{{ record[row.dataIndex] }}</template>
|
<template v-else-if="row.dataIndex && row.dataIndex.indexOf('.') !== -1">
|
||||||
|
{{ get(record, row.dataIndex) }}
|
||||||
|
</template>
|
||||||
|
<template v-else-if="row.formType === 'upload'">
|
||||||
|
<a-link @click="imageSee(row, record, row.dataIndex)"><icon-image /> 查看图片</a-link>
|
||||||
|
</template>
|
||||||
|
<template v-else>{{ record[row.dataIndex] }}</template>
|
||||||
|
|
||||||
|
<a-link
|
||||||
|
class="absolute top-1 right-0"
|
||||||
|
v-if="row?.quickEdit && allowQuickEdit(row.formType) && !row.isEdit"
|
||||||
|
@click="quickEdit(row, record)"
|
||||||
|
>
|
||||||
|
<icon-edit />
|
||||||
|
</a-link>
|
||||||
|
</span>
|
||||||
</slot>
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
</a-table-column>
|
</a-table-column>
|
||||||
@@ -161,7 +236,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { inject } from "vue"
|
import { inject, ref, provide } from "vue"
|
||||||
import config from "@/config/crud"
|
import config from "@/config/crud"
|
||||||
import uploadConfig from "@/config/upload"
|
import uploadConfig from "@/config/upload"
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
@@ -170,15 +245,17 @@ import CustomRender from "../js/custom-render"
|
|||||||
import tool from "@/utils/tool"
|
import tool from "@/utils/tool"
|
||||||
import commonApi from "@/api/common"
|
import commonApi from "@/api/common"
|
||||||
|
|
||||||
|
import formInput from "@cps/ma-form/formItem/form-input.vue"
|
||||||
|
|
||||||
const emit = defineEmits(["refresh", "showImage"])
|
const emit = defineEmits(["refresh", "showImage"])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
columns: Array,
|
columns: Array,
|
||||||
isRecovery: Boolean,
|
isRecovery: Boolean,
|
||||||
crudFormRef: Object
|
crudFormRef: Object
|
||||||
})
|
})
|
||||||
|
|
||||||
const options = inject("options")
|
const options = inject("options")
|
||||||
const requestParams = inject("requestParams")
|
const requestParams = inject("requestParams")
|
||||||
|
const dicts = inject("dicts")
|
||||||
const dictTrans = inject("dictTrans")
|
const dictTrans = inject("dictTrans")
|
||||||
const dictColors = inject("dictColors")
|
const dictColors = inject("dictColors")
|
||||||
|
|
||||||
@@ -189,29 +266,15 @@ const imageSee = async (row, record, dataIndex) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!["id", "hash"].includes(row.returnType)) {
|
if (row.returnType === "hash") {
|
||||||
Message.info("该图片无法查看")
|
emit("showImage", tool.showFile(record[dataIndex]))
|
||||||
return
|
|
||||||
}
|
|
||||||
Message.info("获取图片中,请稍等...")
|
|
||||||
const res =
|
|
||||||
row.returnType === "id"
|
|
||||||
? await commonApi.getFileInfoById({ id: record.id })
|
|
||||||
: await commonApi.getFileInfoByHash({ hash: record.hash })
|
|
||||||
const result = res?.success ?? false
|
|
||||||
if (!result) {
|
|
||||||
Message.info("图片信息无法获取")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const isImage = res.data.mime_type.indexOf("image") > -1
|
if (row.returnType === "id") {
|
||||||
result &&
|
Message.info("该图片无法查看")
|
||||||
emit(
|
return
|
||||||
"showImage",
|
}
|
||||||
isImage
|
|
||||||
? tool.attachUrl(res.data.url, uploadConfig.storageMode[res.data.storage_mode])
|
|
||||||
: "not-image.png"
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
if (!record[row.dataIndex]) {
|
if (!record[row.dataIndex]) {
|
||||||
Message.info("无图片")
|
Message.info("无图片")
|
||||||
@@ -248,8 +311,21 @@ const getIndex = (rowIndex) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const seeAction = (record) => {
|
||||||
|
if (isFunction(options.beforeOpenSee) && !options.beforeOpenSee(record)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (options.see.action && isFunction(options.see.action)) {
|
||||||
|
options.see.action(record)
|
||||||
|
} else {
|
||||||
|
props.crudFormRef.see(record)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const editAction = (record) => {
|
const editAction = (record) => {
|
||||||
isFunction(options.beforeOpenEdit) && options.beforeOpenEdit(record)
|
if (isFunction(options.beforeOpenEdit) && !options.beforeOpenEdit(record)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if (options.edit.action && isFunction(options.edit.action)) {
|
if (options.edit.action && isFunction(options.edit.action)) {
|
||||||
options.edit.action(record)
|
options.edit.action(record)
|
||||||
} else {
|
} else {
|
||||||
@@ -257,6 +333,25 @@ const editAction = (record) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const allowQuickEdit = (formType) => ["select", "input", "input-number", "radio"].includes(formType ?? "input")
|
||||||
|
|
||||||
|
const quickEdit = (row, record) => {
|
||||||
|
if (row.formType === "select" || row.formType === "radio") {
|
||||||
|
record[row.dataIndex] = record[row.dataIndex].toString()
|
||||||
|
}
|
||||||
|
row.isEdit = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateQuickEditData = async (row, record) => {
|
||||||
|
if (isFunction(options.beforeEdit) && !(await options.beforeEdit(record))) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const response = await options.edit.api(record[options.pk], record)
|
||||||
|
row.isEdit = false
|
||||||
|
isFunction(options.afterEdit) && (await options.afterEdit(response, record))
|
||||||
|
Message.success(response.message || `修改成功!`)
|
||||||
|
}
|
||||||
|
|
||||||
const recoveryAction = async (record) => {
|
const recoveryAction = async (record) => {
|
||||||
const response = await options.recovery.api({ ids: [record[options.pk]] })
|
const response = await options.recovery.api({ ids: [record[options.pk]] })
|
||||||
response.success && Message.success(response.message || `恢复成功!`)
|
response.success && Message.success(response.message || `恢复成功!`)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, watch, nextTick } from "vue"
|
import { ref, inject, watch, nextTick } from "vue"
|
||||||
import checkAuth from "@/directives/auth/auth"
|
import checkAuth from "@/directives/auth/auth"
|
||||||
import { isArray } from "lodash"
|
import { isArray } from "lodash-es"
|
||||||
|
|
||||||
const left = ref(0)
|
const left = ref(0)
|
||||||
const top = ref(0)
|
const top = ref(0)
|
||||||
@@ -100,7 +100,11 @@ const openContextMenu = async (ev, record) => {
|
|||||||
currentRow.value = record
|
currentRow.value = record
|
||||||
await nextTick(() => {
|
await nextTick(() => {
|
||||||
const domHeight = document.querySelector(".ma-crud-contextmenu").offsetHeight
|
const domHeight = document.querySelector(".ma-crud-contextmenu").offsetHeight
|
||||||
top.value = ev.clientY - domHeight
|
if (document.body.offsetHeight - ev.pageY < domHeight) {
|
||||||
|
top.value = ev.clientY - domHeight
|
||||||
|
} else {
|
||||||
|
top.value = ev.clientY
|
||||||
|
}
|
||||||
left.value = ev.clientX
|
left.value = ev.clientX
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- add:on-before-cancel -->
|
<!-- 修改源码:添加mask-closable属性 -->
|
||||||
|
<!-- 修改源码:添加on-before-cancel属性 -->
|
||||||
<component
|
<component
|
||||||
:is="componentName"
|
:is="componentName"
|
||||||
v-model:visible="dataVisible"
|
v-model:visible="dataVisible"
|
||||||
@@ -16,7 +17,7 @@
|
|||||||
>
|
>
|
||||||
<template #title>{{ actionTitle }}</template>
|
<template #title>{{ actionTitle }}</template>
|
||||||
<a-spin :loading="dataLoading" tip="加载中..." class="w-full">
|
<a-spin :loading="dataLoading" tip="加载中..." class="w-full">
|
||||||
<ma-form v-model="form" :columns="formColumns" :options="{ showButtons: false }" ref="maFormRef">
|
<ma-form v-model="form" :columns="formColumns" :options="formOptions" ref="maFormRef">
|
||||||
<template v-for="slot in Object.keys($slots)" #[slot]="component">
|
<template v-for="slot in Object.keys($slots)" #[slot]="component">
|
||||||
<slot :name="slot" v-bind="component" />
|
<slot :name="slot" v-bind="component" />
|
||||||
</template>
|
</template>
|
||||||
@@ -26,43 +27,53 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, toRaw, getCurrentInstance, inject, provide } from "vue"
|
import { ref, toRaw, inject, provide, nextTick } from "vue" // 这里多了nextTick
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
import { containerItems } from "@cps/ma-form/js/utils"
|
import { containerItems } from "@cps/ma-form/js/utils"
|
||||||
import { isArray, isFunction, get, cloneDeep, isUndefined } from "lodash"
|
import { isArray, isFunction, get, cloneDeep, isUndefined } from "lodash-es"
|
||||||
import { useRouter } from "vue-router"
|
import { useRouter } from "vue-router"
|
||||||
import tool from "@/utils/tool"
|
import tool from "@/utils/tool"
|
||||||
import { useFormStore } from "@/store/index"
|
import { useFormStore } from "@/store/index"
|
||||||
|
|
||||||
const formStore = useFormStore()
|
const formStore = useFormStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const app = getCurrentInstance().appContext.app
|
const formOptions = ref({ showButtons: false })
|
||||||
const maFormRef = ref()
|
const maFormRef = ref()
|
||||||
const componentName = ref("a-modal")
|
const componentName = ref("a-modal")
|
||||||
const columns = inject("columns")
|
|
||||||
const layoutColumns = ref(new Map())
|
const layoutColumns = ref(new Map())
|
||||||
const options = inject("options")
|
|
||||||
const formColumns = ref([])
|
const formColumns = ref([])
|
||||||
const currentAction = ref("")
|
const currentAction = ref("")
|
||||||
const dataVisible = ref(false)
|
const dataVisible = ref(false)
|
||||||
const form = ref({})
|
const form = ref({})
|
||||||
const actionTitle = ref("")
|
const actionTitle = ref("")
|
||||||
const dataLoading = ref(true)
|
const dataLoading = ref(true)
|
||||||
|
|
||||||
|
const columns = inject("columns")
|
||||||
|
const options = inject("options")
|
||||||
|
// 修改源码:新增事件beforeCancel和处理函数beforeCancel
|
||||||
const emit = defineEmits(["success", "error", "beforeCancel"])
|
const emit = defineEmits(["success", "error", "beforeCancel"])
|
||||||
|
const beforeCancel = () => {
|
||||||
|
emit("beforeCancel")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
provide("form", toRaw(form))
|
provide("form", toRaw(form))
|
||||||
|
if (window.screen.width < 768) {
|
||||||
|
options.formOption.width = window.screen.width
|
||||||
|
options.formOption.isFull = true
|
||||||
|
}
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
const formData = maFormRef.value.getFormData()
|
const formData = maFormRef.value.getFormData()
|
||||||
if (await maFormRef.value.validateForm()) {
|
if (await maFormRef.value.validateForm()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
let response
|
let response
|
||||||
// 在这里添加我们自定义的parameters,注意判断options中是否有parameters-key
|
|
||||||
if (currentAction.value === "add") {
|
if (currentAction.value === "add") {
|
||||||
isFunction(options.beforeAdd) && (await options.beforeAdd(formData))
|
if (isFunction(options.beforeAdd) && !(await options.beforeAdd(formData))) {
|
||||||
// 首先判断是否options.parameters存在
|
return false
|
||||||
|
}
|
||||||
|
// 修改源码添加parameters参数
|
||||||
if (!options.parameters) {
|
if (!options.parameters) {
|
||||||
response = await options.add.api(formData)
|
response = await options.add.api(formData)
|
||||||
} else {
|
} else {
|
||||||
@@ -70,8 +81,9 @@ const submit = async () => {
|
|||||||
}
|
}
|
||||||
isFunction(options.afterAdd) && (await options.afterAdd(response, formData))
|
isFunction(options.afterAdd) && (await options.afterAdd(response, formData))
|
||||||
} else {
|
} else {
|
||||||
isFunction(options.beforeEdit) && (await options.beforeEdit(formData))
|
if (isFunction(options.beforeEdit) && !(await options.beforeEdit(formData))) {
|
||||||
// 编辑也需要更新
|
return false
|
||||||
|
}
|
||||||
if (!options.parameters) {
|
if (!options.parameters) {
|
||||||
response = await options.edit.api(formData[options.pk], formData)
|
response = await options.edit.api(formData[options.pk], formData)
|
||||||
} else {
|
} else {
|
||||||
@@ -84,6 +96,7 @@ const submit = async () => {
|
|||||||
emit("success", response)
|
emit("success", response)
|
||||||
return true
|
return true
|
||||||
} else if (response.success === false && (typeof response.code === "undefined" || response.code !== 200)) {
|
} else if (response.success === false && (typeof response.code === "undefined" || response.code !== 200)) {
|
||||||
|
Message.clear()
|
||||||
Message.error(response.message || `${actionTitle.value}失败!`)
|
Message.error(response.message || `${actionTitle.value}失败!`)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -92,7 +105,7 @@ const open = () => {
|
|||||||
formColumns.value = []
|
formColumns.value = []
|
||||||
layoutColumns.value = new Map()
|
layoutColumns.value = new Map()
|
||||||
init()
|
init()
|
||||||
if (options.formOption.viewType === "tag") {
|
if (options.formOption.viewType === "tag" && currentAction.value !== "see") {
|
||||||
if (!options.formOption.tagId) {
|
if (!options.formOption.tagId) {
|
||||||
Message.info("未配置 tagId")
|
Message.info("未配置 tagId")
|
||||||
return
|
return
|
||||||
@@ -103,6 +116,7 @@ const open = () => {
|
|||||||
}
|
}
|
||||||
const config = {
|
const config = {
|
||||||
options,
|
options,
|
||||||
|
sourceColumns: columns.value,
|
||||||
formColumns: formColumns.value
|
formColumns: formColumns.value
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +142,6 @@ const open = () => {
|
|||||||
} else {
|
} else {
|
||||||
formStore.formList[options.formOption.tagId].editData[queryParams.key] = cloneDeep(form.value)
|
formStore.formList[options.formOption.tagId].editData[queryParams.key] = cloneDeep(form.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
form.value = {}
|
form.value = {}
|
||||||
router.push(`/openForm/${options.formOption.tagId}` + tool.httpBuild(queryParams, true))
|
router.push(`/openForm/${options.formOption.tagId}` + tool.httpBuild(queryParams, true))
|
||||||
} else {
|
} else {
|
||||||
@@ -136,17 +149,13 @@ const open = () => {
|
|||||||
dataVisible.value = true
|
dataVisible.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ~~~~addMethod~~~~
|
|
||||||
const beforeCancel = () => {
|
|
||||||
emit("beforeCancel")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
const close = () => {
|
const close = () => {
|
||||||
dataVisible.value = false
|
dataVisible.value = false
|
||||||
formColumns.value = []
|
formColumns.value = []
|
||||||
form.value = {}
|
form.value = {}
|
||||||
}
|
}
|
||||||
const add = () => {
|
const add = async () => {
|
||||||
|
// 修改源码:开始
|
||||||
const strArr = ["新增编辑", "编辑新增", "新增新增", "编辑编辑", "编辑", "新增"]
|
const strArr = ["新增编辑", "编辑新增", "新增新增", "编辑编辑", "编辑", "新增"]
|
||||||
if (!actionTitle.value) {
|
if (!actionTitle.value) {
|
||||||
actionTitle.value = "新增"
|
actionTitle.value = "新增"
|
||||||
@@ -155,11 +164,15 @@ const add = () => {
|
|||||||
} else {
|
} else {
|
||||||
actionTitle.value += "新增"
|
actionTitle.value += "新增"
|
||||||
}
|
}
|
||||||
|
// 修改源码:结束
|
||||||
currentAction.value = "add"
|
currentAction.value = "add"
|
||||||
|
formOptions.value["disabled"] = false
|
||||||
form.value = {}
|
form.value = {}
|
||||||
open()
|
open()
|
||||||
|
await nextTick(() => maFormRef.value && maFormRef.value.updateOptions())
|
||||||
}
|
}
|
||||||
const edit = (data) => {
|
const edit = async (data) => {
|
||||||
|
// 修改源码:开始
|
||||||
const strArr = ["新增编辑", "编辑新增", "新增新增", "编辑编辑", "编辑", "新增"]
|
const strArr = ["新增编辑", "编辑新增", "新增新增", "编辑编辑", "编辑", "新增"]
|
||||||
if (!actionTitle.value) {
|
if (!actionTitle.value) {
|
||||||
actionTitle.value = "编辑"
|
actionTitle.value = "编辑"
|
||||||
@@ -168,32 +181,66 @@ const edit = (data) => {
|
|||||||
} else {
|
} else {
|
||||||
actionTitle.value += "编辑"
|
actionTitle.value += "编辑"
|
||||||
}
|
}
|
||||||
|
// 修改源码:结束
|
||||||
currentAction.value = "edit"
|
currentAction.value = "edit"
|
||||||
|
formOptions.value["disabled"] = false
|
||||||
form.value = {}
|
form.value = {}
|
||||||
for (let i in data) form.value[i] = data[i]
|
if (options.edit.dataSource && options.edit.dataSource === "api") {
|
||||||
open(data)
|
const response = await options.edit.dataSourceApi(data[options.pk])
|
||||||
|
if (response.success) {
|
||||||
|
form.value = response.data
|
||||||
|
open(response.data)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (let i in data) form.value[i] = data[i]
|
||||||
|
open(data)
|
||||||
|
}
|
||||||
|
await nextTick(() => maFormRef.value && maFormRef.value.updateOptions())
|
||||||
|
}
|
||||||
|
const see = async (data) => {
|
||||||
|
actionTitle.value = options.see.title ?? "查看"
|
||||||
|
currentAction.value = "see"
|
||||||
|
formOptions.value["disabled"] = true
|
||||||
|
form.value = {}
|
||||||
|
if (options.see.dataSource && options.see.dataSource === "api") {
|
||||||
|
const response = await options.see.dataSourceApi(data[options.pk])
|
||||||
|
if (response.success) {
|
||||||
|
form.value = response.data
|
||||||
|
open(response.data)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (let i in data) form.value[i] = data[i]
|
||||||
|
open(data)
|
||||||
|
}
|
||||||
|
await nextTick(() => maFormRef.value && maFormRef.value.updateOptions())
|
||||||
}
|
}
|
||||||
|
|
||||||
const init = () => {
|
const init = async () => {
|
||||||
dataLoading.value = true
|
dataLoading.value = true
|
||||||
const layout = JSON.parse(JSON.stringify(options?.formOption?.layout ?? []))
|
const layout = JSON.parse(JSON.stringify(options?.formOption?.layout ?? []))
|
||||||
// const layout = options?.formOption?.layout ?? []
|
|
||||||
columns.map(async (item) => {
|
await Promise.all(
|
||||||
await columnItemHandle(item)
|
columns.value.map(async (item) => {
|
||||||
})
|
if (item.children && item.children.length > 0) {
|
||||||
|
await item.children.map(async (childItem) => {
|
||||||
|
await columnItemHandle(childItem)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
await columnItemHandle(item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
// 设置表单布局
|
// 设置表单布局
|
||||||
settingFormLayout(layout)
|
settingFormLayout(layout)
|
||||||
if (isArray(layout) && layout.length > 0) {
|
if (isArray(layout) && layout.length > 0) {
|
||||||
formColumns.value = layout
|
formColumns.value = layout
|
||||||
const excludeColumns = ["__index", "__operation"]
|
const excludeColumns = ["__index", "__operation"]
|
||||||
columns.map((item) => {
|
columns.value.map((item) => {
|
||||||
if (options.formExcludePk) excludeColumns.push(options.pk)
|
if (options.formExcludePk) excludeColumns.push(options.pk)
|
||||||
if (excludeColumns.includes(item.dataIndex)) return
|
if (excludeColumns.includes(item.dataIndex)) return
|
||||||
!item.__formLayoutSetting && formColumns.value.push(item)
|
!item.__formLayoutSetting && formColumns.value.push(item)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
dataLoading.value = false
|
dataLoading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,28 +254,33 @@ const columnItemHandle = async (item) => {
|
|||||||
layoutColumns.value.set(item.dataIndex, item)
|
layoutColumns.value.set(item.dataIndex, item)
|
||||||
formColumns.value.push(item)
|
formColumns.value.push(item)
|
||||||
|
|
||||||
// 针对带点的数据处理
|
if (options.formOption.viewType !== "tag") {
|
||||||
if (item.dataIndex && item.dataIndex.indexOf(".") > -1) {
|
// 针对带点的数据处理
|
||||||
form.value[item.dataIndex] = get(form.value, item.dataIndex)
|
if (item.dataIndex && item.dataIndex.indexOf(".") > -1) {
|
||||||
}
|
form.value[item.dataIndex] = get(form.value, item.dataIndex)
|
||||||
|
|
||||||
// add 默认值处理
|
|
||||||
if (currentAction.value === "add") {
|
|
||||||
if (item.addDefaultValue && isFunction(item.addDefaultValue)) {
|
|
||||||
form.value[item.dataIndex] = await item.addDefaultValue(form.value)
|
|
||||||
} else if (typeof item.addDefaultValue != "undefined") {
|
|
||||||
form.value[item.dataIndex] = item.addDefaultValue
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// edit 默认值处理
|
// add 默认值处理
|
||||||
if (currentAction.value === "edit") {
|
if (currentAction.value === "add") {
|
||||||
if (item.editDefaultValue && isFunction(item.editDefaultValue)) {
|
if (item.addDefaultValue && isFunction(item.addDefaultValue)) {
|
||||||
form.value[item.dataIndex] = await item.editDefaultValue(form.value)
|
form.value[item.dataIndex] = await item.addDefaultValue(form.value)
|
||||||
} else if (typeof item.editDefaultValue != "undefined") {
|
} else if (typeof item.addDefaultValue != "undefined") {
|
||||||
form.value[item.dataIndex] = item.editDefaultValue
|
form.value[item.dataIndex] = item.addDefaultValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// edit 和 see 默认值处理
|
||||||
|
if (currentAction.value === "edit" || currentAction.value === "see") {
|
||||||
|
if (item.editDefaultValue && isFunction(item.editDefaultValue)) {
|
||||||
|
form.value[item.dataIndex] = await item.editDefaultValue(form.value)
|
||||||
|
} else if (typeof item.editDefaultValue != "undefined") {
|
||||||
|
form.value[item.dataIndex] = item.editDefaultValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item.disabled = undefined
|
||||||
|
item.readonly = undefined
|
||||||
|
await nextTick()
|
||||||
// 其他处理
|
// 其他处理
|
||||||
item.display = formItemShow(item)
|
item.display = formItemShow(item)
|
||||||
item.disabled = formItemDisabled(item)
|
item.disabled = formItemDisabled(item)
|
||||||
@@ -236,6 +288,7 @@ const columnItemHandle = async (item) => {
|
|||||||
item.labelWidth = formItemLabelWidth(item)
|
item.labelWidth = formItemLabelWidth(item)
|
||||||
item.rules = getRules(item)
|
item.rules = getRules(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingFormLayout = (layout) => {
|
const settingFormLayout = (layout) => {
|
||||||
if (!isArray(layout)) {
|
if (!isArray(layout)) {
|
||||||
return
|
return
|
||||||
@@ -306,19 +359,22 @@ const settingFormLayout = (layout) => {
|
|||||||
|
|
||||||
const formItemShow = (item) => {
|
const formItemShow = (item) => {
|
||||||
if (currentAction.value === "add") {
|
if (currentAction.value === "add") {
|
||||||
return item.addDisplay !== false
|
return isFunction(item.addDisplay) ? item.addDisplay() !== false : item.addDisplay !== false
|
||||||
}
|
}
|
||||||
if (currentAction.value === "edit") {
|
if (currentAction.value === "edit" || currentAction.value === "see") {
|
||||||
return item.editDisplay !== false
|
return isFunction(item.editDisplay) ? item.editDisplay(form.value) !== false : item.editDisplay !== false
|
||||||
}
|
}
|
||||||
return item.display !== false
|
return item.display !== false
|
||||||
}
|
}
|
||||||
const formItemDisabled = (item) => {
|
const formItemDisabled = (item) => {
|
||||||
if (currentAction.value === "add" && !isUndefined(item.addDisabled)) {
|
if (currentAction.value === "add" && !isUndefined(item.addDisabled)) {
|
||||||
return item.addDisabled
|
return isFunction(item.addDisabled) ? item.addDisabled() : item.addDisabled
|
||||||
}
|
}
|
||||||
if (currentAction.value === "edit" && !isUndefined(item.editDisabled)) {
|
if (currentAction.value === "edit" && !isUndefined(item.editDisabled)) {
|
||||||
return item.editDisabled
|
return isFunction(item.editDisabled) ? item.editDisabled(form.value) : item.editDisabled
|
||||||
|
}
|
||||||
|
if (currentAction.value === "see") {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (!isUndefined(item.disabled)) {
|
if (!isUndefined(item.disabled)) {
|
||||||
return item.disabled
|
return item.disabled
|
||||||
@@ -327,10 +383,13 @@ const formItemDisabled = (item) => {
|
|||||||
}
|
}
|
||||||
const formItemReadonly = (item) => {
|
const formItemReadonly = (item) => {
|
||||||
if (currentAction.value === "add" && !isUndefined(item.addReadonly)) {
|
if (currentAction.value === "add" && !isUndefined(item.addReadonly)) {
|
||||||
return item.addReadonly
|
return isFunction(item.addReadonly) ? item.addReadonly() : item.addReadonly
|
||||||
}
|
}
|
||||||
if (currentAction.value === "edit" && !isUndefined(item.editReadonly)) {
|
if (currentAction.value === "edit" && !isUndefined(item.editReadonly)) {
|
||||||
return item.editReadonly
|
return isFunction(item.editReadonly) ? item.editReadonly(form.value) : item.editReadonly
|
||||||
|
}
|
||||||
|
if (currentAction.value === "see") {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
if (!isUndefined(item.readonly)) {
|
if (!isUndefined(item.readonly)) {
|
||||||
return item.readonly
|
return item.readonly
|
||||||
@@ -371,5 +430,6 @@ const getFormColumns = async (type = "add") => {
|
|||||||
await init()
|
await init()
|
||||||
return formColumns.value
|
return formColumns.value
|
||||||
}
|
}
|
||||||
defineExpose({ add, edit, currentAction, form, getFormColumns, actionTitle })
|
// 修改源码,暴露actionTitle
|
||||||
|
defineExpose({ add, edit, see, currentAction, form, getFormColumns, maFormRef, actionTitle })
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-modal v-model:visible="visible" :footer="false" @cancel="close" draggable>
|
<a-modal v-model:visible="visible" :footer="false" @cancel="close" draggable>
|
||||||
@@ -37,6 +32,7 @@ import { Message } from "@arco-design/web-vue"
|
|||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
|
|
||||||
const options = inject("options")
|
const options = inject("options")
|
||||||
|
const emit = defineEmits(["success"])
|
||||||
|
|
||||||
const open = () => (visible.value = true)
|
const open = () => (visible.value = true)
|
||||||
const close = () => (visible.value = false)
|
const close = () => (visible.value = false)
|
||||||
@@ -46,8 +42,9 @@ const upload = (fileOption) => {
|
|||||||
|
|
||||||
const dataForm = new FormData()
|
const dataForm = new FormData()
|
||||||
dataForm.append("file", fileOption.fileItem.file)
|
dataForm.append("file", fileOption.fileItem.file)
|
||||||
commonApi.importExcel(options.import.url, dataForm).then((res) => {
|
commonApi.importExcel(options.import.url, dataForm).then(async (res) => {
|
||||||
res.success && Message.success(res.message || "导入成功")
|
res.success && Message.success(res.message || "导入成功")
|
||||||
|
emit("success")
|
||||||
close()
|
close()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-spin :loading="searchLoading" :tip="options.searchLoadingText" v-if="showSearch">
|
<a-spin :loading="searchLoading" :tip="options.searchLoadingText" v-if="showSearch">
|
||||||
@@ -25,7 +20,10 @@
|
|||||||
:label-col-style="{ width: component.searchLabelWidth ?? options.searchLabelWidth }"
|
:label-col-style="{ width: component.searchLabelWidth ?? options.searchLabelWidth }"
|
||||||
>
|
>
|
||||||
<slot :name="`${component.dataIndex}`" v-bind="{ searchForm, component }">
|
<slot :name="`${component.dataIndex}`" v-bind="{ searchForm, component }">
|
||||||
<component :is="getComponentName(component.formType)" :component="component" />
|
<component
|
||||||
|
:is="getComponentName(component.searchFormType ?? component.formType)"
|
||||||
|
:component="component"
|
||||||
|
/>
|
||||||
</slot>
|
</slot>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</template>
|
</template>
|
||||||
@@ -57,7 +55,7 @@ import MaFormPicker from "./searchFormItem/form-picker.vue"
|
|||||||
import MaFormSelect from "./searchFormItem/form-select.vue"
|
import MaFormSelect from "./searchFormItem/form-select.vue"
|
||||||
import MaFormCascader from "./searchFormItem/form-cascader.vue"
|
import MaFormCascader from "./searchFormItem/form-cascader.vue"
|
||||||
import MaFormTreeSelect from "./searchFormItem/form-tree-select.vue"
|
import MaFormTreeSelect from "./searchFormItem/form-tree-select.vue"
|
||||||
import { cloneDeep, isFunction } from "lodash"
|
import { cloneDeep, isFunction } from "lodash-es"
|
||||||
|
|
||||||
const options = inject("options")
|
const options = inject("options")
|
||||||
const columns = inject("columns")
|
const columns = inject("columns")
|
||||||
@@ -73,14 +71,30 @@ const searchColumns = ref([])
|
|||||||
const searchForm = ref({})
|
const searchForm = ref({})
|
||||||
|
|
||||||
provide("searchForm", searchForm)
|
provide("searchForm", searchForm)
|
||||||
provide("columns", columns)
|
|
||||||
|
|
||||||
const emit = defineEmits(["search"])
|
const emit = defineEmits(["search"])
|
||||||
|
|
||||||
if (columns.length > 0) {
|
const getSearchAllColumns = (cls = []) => {
|
||||||
searchColumns.value = cloneDeep(
|
let sls = []
|
||||||
columns.filter((item) => item.search === true && options.tabs?.dataIndex != item.dataIndex)
|
cls.map((item) => {
|
||||||
)
|
if (item.children && item.children.length > 0) {
|
||||||
|
let tmp = getSearchAllColumns(item.children)
|
||||||
|
sls.push(...tmp)
|
||||||
|
} else if (item.dataIndex && item.search && item.search === true) {
|
||||||
|
sls.push(item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return sls
|
||||||
|
}
|
||||||
|
|
||||||
|
const initSearchColumns = () => {
|
||||||
|
if (columns.value.length > 0) {
|
||||||
|
searchColumns.value = cloneDeep(
|
||||||
|
getSearchAllColumns(columns.value).filter(
|
||||||
|
(item) => item.search === true && options.tabs?.dataIndex != item.dataIndex
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlerSearch = () => {
|
const handlerSearch = () => {
|
||||||
@@ -89,6 +103,13 @@ const handlerSearch = () => {
|
|||||||
|
|
||||||
const resetSearch = async () => {
|
const resetSearch = async () => {
|
||||||
searchRef.value.resetFields()
|
searchRef.value.resetFields()
|
||||||
|
Object.keys(searchForm.value).map((item) => {
|
||||||
|
let temp = item.match(/^(.+)Min$/)
|
||||||
|
if (temp) {
|
||||||
|
searchForm.value[temp[1] + "Min"] = undefined
|
||||||
|
searchForm.value[temp[1] + "Max"] = undefined
|
||||||
|
}
|
||||||
|
})
|
||||||
if (options.resetSearch && isFunction(options.resetSearch)) {
|
if (options.resetSearch && isFunction(options.resetSearch)) {
|
||||||
await options.resetSearch(searchForm.value)
|
await options.resetSearch(searchForm.value)
|
||||||
}
|
}
|
||||||
@@ -117,6 +138,8 @@ const getComponentName = (formType) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initSearchColumns()
|
||||||
|
|
||||||
const setSearchHidden = () => (showSearch.value = false)
|
const setSearchHidden = () => (showSearch.value = false)
|
||||||
const setSearchDisplay = () => (showSearch.value = true)
|
const setSearchDisplay = () => (showSearch.value = true)
|
||||||
const setSearchLoading = () => (searchLoading.value = true)
|
const setSearchLoading = () => (searchLoading.value = true)
|
||||||
@@ -125,9 +148,11 @@ const getSearchFormRef = () => searchRef.value
|
|||||||
const getSearchColumns = () => searchColumns.value
|
const getSearchColumns = () => searchColumns.value
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
initSearchColumns,
|
||||||
getSearchFormRef,
|
getSearchFormRef,
|
||||||
getSearchColumns,
|
getSearchColumns,
|
||||||
showSearch,
|
showSearch,
|
||||||
|
resetSearch,
|
||||||
setSearchHidden,
|
setSearchHidden,
|
||||||
setSearchDisplay,
|
setSearchDisplay,
|
||||||
setSearchLoading,
|
setSearchLoading,
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-cascader
|
<a-cascader
|
||||||
@@ -21,7 +16,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, watch } from "vue"
|
import { ref, inject, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object
|
component: Object
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,30 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
|
<a-input-group v-if="props.component.formType === 'input-number' && (props.component?.rangeSearch ?? false)">
|
||||||
|
<a-input-number
|
||||||
|
v-model="minData"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="props.component.searchPlaceholder ?? `请输入${props.component.title}最小值`"
|
||||||
|
/>
|
||||||
|
<span class="p-1">~</span>
|
||||||
|
<a-input-number
|
||||||
|
v-model="maxData"
|
||||||
|
allow-clear
|
||||||
|
:placeholder="props.component.searchPlaceholder ?? `请输入${props.component.title}最大值`"
|
||||||
|
/>
|
||||||
|
</a-input-group>
|
||||||
|
|
||||||
|
<a-input-number
|
||||||
|
v-else-if="props.component.formType === 'input-number'"
|
||||||
|
v-model="value"
|
||||||
|
:placeholder="props.component.searchPlaceholder ?? `请输入${props.component.title}`"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
<a-input
|
<a-input
|
||||||
|
v-else
|
||||||
v-model="value"
|
v-model="value"
|
||||||
:placeholder="props.component.searchPlaceholder ?? `请输入${props.component.title}`"
|
:placeholder="props.component.searchPlaceholder ?? `请输入${props.component.title}`"
|
||||||
allow-clear
|
allow-clear
|
||||||
@@ -8,14 +33,36 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, watch } from "vue"
|
import { ref, inject, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set, isArray } from "lodash-es"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object
|
component: Object
|
||||||
})
|
})
|
||||||
const searchForm = inject("searchForm")
|
const searchForm = inject("searchForm")
|
||||||
|
const minData = ref(isArray(props.component?.searchDefaultValue) ? props.component?.searchDefaultValue[0] : undefined)
|
||||||
|
const maxData = ref(isArray(props.component?.searchDefaultValue) ? props.component?.searchDefaultValue[1] : undefined)
|
||||||
|
const value = ref(
|
||||||
|
get(
|
||||||
|
searchForm.value,
|
||||||
|
props.component.dataIndex,
|
||||||
|
(props.component.searchDefaultValue ?? props.component.formType === "input-number") ? 0 : ""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
const value = ref(get(searchForm.value, props.component.dataIndex, props.component.searchDefaultValue ?? ""))
|
if (props.component.formType === "input-number" && (props.component?.rangeSearch ?? false)) {
|
||||||
set(searchForm.value, props.component.dataIndex, value.value)
|
set(searchForm.value, `${props.component.dataIndex}Min`, minData.value)
|
||||||
|
set(searchForm.value, `${props.component.dataIndex}Max`, maxData.value)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => get(searchForm.value, props.component.dataIndex + "Min"),
|
||||||
|
(vl) => (minData.value = vl)
|
||||||
|
)
|
||||||
|
watch(
|
||||||
|
() => get(searchForm.value, props.component.dataIndex + "Max"),
|
||||||
|
(vl) => (maxData.value = vl)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
set(searchForm.value, props.component.dataIndex, value.value)
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => get(searchForm.value, props.component.dataIndex),
|
() => get(searchForm.value, props.component.dataIndex),
|
||||||
@@ -25,4 +72,12 @@ watch(
|
|||||||
() => value.value,
|
() => value.value,
|
||||||
(v) => set(searchForm.value, props.component.dataIndex, v)
|
(v) => set(searchForm.value, props.component.dataIndex, v)
|
||||||
)
|
)
|
||||||
|
watch(
|
||||||
|
() => minData.value,
|
||||||
|
(v) => set(searchForm.value, `${props.component.dataIndex}Min`, v)
|
||||||
|
)
|
||||||
|
watch(
|
||||||
|
() => maxData.value,
|
||||||
|
(v) => set(searchForm.value, `${props.component.dataIndex}Max`, v)
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<component
|
<component
|
||||||
@@ -18,6 +13,7 @@
|
|||||||
"
|
"
|
||||||
:time-picker-props="props.component.formType == 'range' ? { defaultValue: ['00:00:00', '23:59:59'] } : {}"
|
:time-picker-props="props.component.formType == 'range' ? { defaultValue: ['00:00:00', '23:59:59'] } : {}"
|
||||||
:show-time="props.component.showTime"
|
:show-time="props.component.showTime"
|
||||||
|
:type="props.component.range ? (props.component.formType === 'time' ? 'time-range' : 'range') : ''"
|
||||||
:format="props.component.format || ''"
|
:format="props.component.format || ''"
|
||||||
:mode="props.component.mode"
|
:mode="props.component.mode"
|
||||||
allow-clear
|
allow-clear
|
||||||
@@ -26,12 +22,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, watch } from "vue"
|
import { inject, computed } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object
|
component: Object
|
||||||
})
|
})
|
||||||
const searchForm = inject("searchForm")
|
const searchForm = inject("searchForm")
|
||||||
|
const emit = defineEmits(["update:modelValue"])
|
||||||
|
|
||||||
const getComponentName = () => {
|
const getComponentName = () => {
|
||||||
if (["date", "month", "year", "week", "quarter", "range", "time"].includes(props.component.formType)) {
|
if (["date", "month", "year", "week", "quarter", "range", "time"].includes(props.component.formType)) {
|
||||||
@@ -39,23 +36,30 @@ const getComponentName = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let defaultValue
|
const value = computed({
|
||||||
|
get() {
|
||||||
|
let val = get(searchForm.value, props.component.dataIndex)
|
||||||
|
if (val === undefined) {
|
||||||
|
if (props.component.formType === "range") {
|
||||||
|
val = props.component.searchDefaultValue ?? []
|
||||||
|
} else {
|
||||||
|
val = props.component.searchDefaultValue ?? ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (props.component.formType === "range") {
|
return val
|
||||||
defaultValue = props.component.searchDefaultValue ?? []
|
},
|
||||||
} else {
|
set(newVal) {
|
||||||
defaultValue = props.component.searchDefaultValue ?? ""
|
if (newVal === undefined) {
|
||||||
}
|
if (props.component.formType === "range") {
|
||||||
|
newVal = []
|
||||||
|
} else {
|
||||||
|
newVal = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const value = ref(get(searchForm.value, props.component.dataIndex, defaultValue))
|
emit("update:modelValue", newVal)
|
||||||
set(searchForm.value, props.component.dataIndex, value.value)
|
set(searchForm.value, props.component.dataIndex, newVal)
|
||||||
|
}
|
||||||
watch(
|
})
|
||||||
() => get(searchForm.value, props.component.dataIndex),
|
|
||||||
(vl) => (value.value = vl)
|
|
||||||
)
|
|
||||||
watch(
|
|
||||||
() => value.value,
|
|
||||||
(v) => set(searchForm.value, props.component.dataIndex, v)
|
|
||||||
)
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,12 +1,3 @@
|
|||||||
<!--
|
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
|
||||||
<template>
|
<template>
|
||||||
<a-select
|
<a-select
|
||||||
v-model="value"
|
v-model="value"
|
||||||
@@ -26,7 +17,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, watch } from "vue"
|
import { ref, inject, watch } from "vue"
|
||||||
import { handlerCascader } from "@cps/ma-form/js/networkRequest"
|
import { handlerCascader } from "@cps/ma-form/js/networkRequest"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object
|
component: Object
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-tree-select
|
<a-tree-select
|
||||||
@@ -23,7 +18,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, watch } from "vue"
|
import { ref, inject, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object
|
component: Object
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-drawer :visible="visible" unmountOnClose :footer="false" :width="900" @cancel="onCancel">
|
<a-drawer :visible="visible" unmountOnClose :footer="false" :width="950" @cancel="onCancel">
|
||||||
<template #title>设置</template>
|
<template #title>设置</template>
|
||||||
|
|
||||||
<a-space class="mt-3">
|
<a-space class="mt-3">
|
||||||
@@ -59,7 +54,12 @@
|
|||||||
<span v-else> / </span>
|
<span v-else> / </span>
|
||||||
</template>
|
</template>
|
||||||
</a-table-column>
|
</a-table-column>
|
||||||
<a-table-column title="隐藏" data-index="hide" align="center">
|
<a-table-column title="搜索隐藏" data-index="hide" align="center">
|
||||||
|
<template #cell="{ record }"
|
||||||
|
><a-checkbox v-model="record.search" @change="changeColumn($event, 'search', record.dataIndex)"
|
||||||
|
/></template>
|
||||||
|
</a-table-column>
|
||||||
|
<a-table-column title="表格隐藏" data-index="hide" align="center">
|
||||||
<template #cell="{ record }"
|
<template #cell="{ record }"
|
||||||
><a-checkbox v-model="record.hide" @change="changeColumn($event, 'hide', record.dataIndex)"
|
><a-checkbox v-model="record.hide" @change="changeColumn($event, 'hide', record.dataIndex)"
|
||||||
/></template>
|
/></template>
|
||||||
@@ -123,16 +123,22 @@
|
|||||||
import { ref, inject } from "vue"
|
import { ref, inject } from "vue"
|
||||||
|
|
||||||
const options = inject("options")
|
const options = inject("options")
|
||||||
let columns = inject("columns")
|
const columns = inject("columns")
|
||||||
|
const allowShowColumns = ref([])
|
||||||
|
|
||||||
const allowShowColumns = columns.filter((item) => {
|
const emit = defineEmits(["onChangeSearchHide", "onChangeColumnHide"])
|
||||||
return !(item?.settingHide ?? false)
|
|
||||||
})
|
const setShowColumns = () => {
|
||||||
|
allowShowColumns.value = columns.value.filter((item) => {
|
||||||
|
return !(item?.settingHide ?? false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const bordered = ref("column")
|
const bordered = ref("column")
|
||||||
|
|
||||||
const open = () => {
|
const open = () => {
|
||||||
|
setShowColumns()
|
||||||
visible.value = true
|
visible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +147,7 @@ const onCancel = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const changeColumn = (ev, type, name) => {
|
const changeColumn = (ev, type, name) => {
|
||||||
const column = columns.find((item) => item.dataIndex === name)
|
const column = columns.value.find((item) => item.dataIndex === name)
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "order":
|
case "order":
|
||||||
if (ev === "page") {
|
if (ev === "page") {
|
||||||
@@ -152,6 +158,12 @@ const changeColumn = (ev, type, name) => {
|
|||||||
column.sortable = undefined
|
column.sortable = undefined
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case "hide":
|
||||||
|
emit("onChangeColumnHide")
|
||||||
|
break
|
||||||
|
case "search":
|
||||||
|
emit("onChangeSearchHide")
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +183,8 @@ const changeBordered = (v) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onTableChange = (_data) => {
|
const onTableChange = (_data) => {
|
||||||
columns = _data
|
columns.value = _data
|
||||||
|
setShowColumns()
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ open })
|
defineExpose({ open })
|
||||||
|
|||||||
@@ -8,14 +8,22 @@
|
|||||||
:type="options.tabs.type"
|
:type="options.tabs.type"
|
||||||
:hide-content="true"
|
:hide-content="true"
|
||||||
@change="tabChange"
|
@change="tabChange"
|
||||||
@tab-click="maEvent.customeEvent(options.tabs, $event, 'onClick')"
|
@tab-click="runEvent(options.tabs, 'onClick', undefined, $event)"
|
||||||
class="ma-tabs mb-5"
|
class="ma-tabs mb-5"
|
||||||
>
|
>
|
||||||
<template #extra><slot name="tabExtra"></slot></template>
|
<template #extra><slot name="tabExtra"></slot></template>
|
||||||
<a-tab-pane :key="item.value" :title="item.label" v-for="item in options.tabs.data"></a-tab-pane>
|
<a-tab-pane :key="item.value" :title="item.label" v-for="item in options.tabs.data">
|
||||||
|
<template #title
|
||||||
|
><slot :name="'tabTitle-' + item.label">{{ item.label }}</slot></template
|
||||||
|
>
|
||||||
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
<ma-search @search="searchSubmitHandler" class="__search-panel" ref="crudSearchRef">
|
<ma-search @search="searchSubmitHandler" class="__search-panel" ref="crudSearchRef">
|
||||||
<template v-for="(slot, slotIndex) in searchSlots" :key="slotIndex" #[slot]="{ searchForm, component }">
|
<template
|
||||||
|
v-for="(slot, slotIndex) in getSearchSlot()"
|
||||||
|
:key="slotIndex"
|
||||||
|
#[slot]="{ searchForm, component }"
|
||||||
|
>
|
||||||
<slot :name="`search-${slot}`" v-bind="{ searchForm, component }" />
|
<slot :name="`search-${slot}`" v-bind="{ searchForm, component }" />
|
||||||
</template>
|
</template>
|
||||||
<template #searchBeforeButtons>
|
<template #searchBeforeButtons>
|
||||||
@@ -28,6 +36,7 @@
|
|||||||
<slot name="searchAfterButtons"></slot>
|
<slot name="searchAfterButtons"></slot>
|
||||||
</template>
|
</template>
|
||||||
</ma-search>
|
</ma-search>
|
||||||
|
<div v-if="$slots.middleContent" class="mb-2"><slot name="middleContent"></slot></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="_crud-content">
|
<div class="_crud-content">
|
||||||
<div class="operation-tools lg:flex justify-between mb-3" ref="crudOperationRef">
|
<div class="operation-tools lg:flex justify-between mb-3" ref="crudOperationRef">
|
||||||
@@ -36,6 +45,8 @@
|
|||||||
<slot name="tableButtons">
|
<slot name="tableButtons">
|
||||||
<a-button
|
<a-button
|
||||||
v-if="options.add.show"
|
v-if="options.add.show"
|
||||||
|
v-auth="options.add.auth || []"
|
||||||
|
v-role="options.add.role || []"
|
||||||
@click="addAction"
|
@click="addAction"
|
||||||
type="primary"
|
type="primary"
|
||||||
class="w-full lg:w-auto mt-2 lg:mt-0"
|
class="w-full lg:w-auto mt-2 lg:mt-0"
|
||||||
@@ -43,9 +54,15 @@
|
|||||||
<template #icon><icon-plus /></template>{{ options.add.text || "新增" }}
|
<template #icon><icon-plus /></template>{{ options.add.text || "新增" }}
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
||||||
<a-popconfirm content="确定要删除数据吗?" position="bottom" @ok="deletesMultipleAction">
|
<a-popconfirm
|
||||||
|
content="确定要删除数据吗?"
|
||||||
|
position="bottom"
|
||||||
|
@ok="deletesMultipleAction"
|
||||||
|
v-if="options.delete.show && isBatch(options.delete) && options.rowSelection"
|
||||||
|
>
|
||||||
<a-button
|
<a-button
|
||||||
v-if="options.delete.show"
|
v-auth="options.delete.auth || []"
|
||||||
|
v-role="options.delete.role || []"
|
||||||
type="primary"
|
type="primary"
|
||||||
status="danger"
|
status="danger"
|
||||||
class="w-full lg:w-auto mt-2 lg:mt-0"
|
class="w-full lg:w-auto mt-2 lg:mt-0"
|
||||||
@@ -55,9 +72,15 @@
|
|||||||
</a-button>
|
</a-button>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
|
|
||||||
<a-popconfirm content="确定要恢复数据吗?" position="bottom" @ok="recoverysMultipleAction">
|
<a-popconfirm
|
||||||
|
content="确定要恢复数据吗?"
|
||||||
|
position="bottom"
|
||||||
|
@ok="recoverysMultipleAction"
|
||||||
|
v-if="options.recovery.show && isRecovery && isBatch(options.delete)"
|
||||||
|
>
|
||||||
<a-button
|
<a-button
|
||||||
v-if="options.recovery.show && isRecovery"
|
v-auth="options.recovery.auth || []"
|
||||||
|
v-role="options.recovery.role || []"
|
||||||
type="primary"
|
type="primary"
|
||||||
status="success"
|
status="success"
|
||||||
class="w-full lg:w-auto mt-2 lg:mt-0"
|
class="w-full lg:w-auto mt-2 lg:mt-0"
|
||||||
@@ -66,11 +89,21 @@
|
|||||||
>
|
>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
|
|
||||||
<a-button v-if="options.import.show" @click="importAction" class="w-full lg:w-auto mt-2 lg:mt-0"
|
<a-button
|
||||||
|
v-if="options.import.show"
|
||||||
|
v-auth="options.import.auth || []"
|
||||||
|
v-role="options.import.role || []"
|
||||||
|
@click="importAction"
|
||||||
|
class="w-full lg:w-auto mt-2 lg:mt-0"
|
||||||
><template #icon><icon-upload /></template>{{ options.import.text || "导入" }}</a-button
|
><template #icon><icon-upload /></template>{{ options.import.text || "导入" }}</a-button
|
||||||
>
|
>
|
||||||
|
|
||||||
<a-button v-if="options.export.show" @click="exportAction" class="w-full lg:w-auto mt-2 lg:mt-0"
|
<a-button
|
||||||
|
v-if="options.export.show"
|
||||||
|
v-auth="options.export.auth || []"
|
||||||
|
v-role="options.export.role || []"
|
||||||
|
@click="exportAction"
|
||||||
|
class="w-full lg:w-auto mt-2 lg:mt-0"
|
||||||
><template #icon><icon-download /></template>{{ options.export.text || "导出" }}</a-button
|
><template #icon><icon-download /></template>{{ options.export.text || "导出" }}</a-button
|
||||||
>
|
>
|
||||||
|
|
||||||
@@ -112,8 +145,9 @@
|
|||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
<div ref="crudContentRef">
|
<div ref="crudContentRef">
|
||||||
<slot name="content" v-bind="tableData">
|
<slot name="crudContent" v-bind="tableData">
|
||||||
<a-table
|
<a-table
|
||||||
|
v-if="tableIsShow"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:key="options.pk"
|
:key="options.pk"
|
||||||
@@ -123,7 +157,7 @@
|
|||||||
:pagination="options.tablePagination"
|
:pagination="options.tablePagination"
|
||||||
:stripe="options.stripe"
|
:stripe="options.stripe"
|
||||||
:bordered="options.bordered"
|
:bordered="options.bordered"
|
||||||
:rowSelection="options.rowSelection || undefined"
|
:rowSelection="options.rowSelection ?? undefined"
|
||||||
:row-key="options?.rowSelection?.key ?? options.pk"
|
:row-key="options?.rowSelection?.key ?? options.pk"
|
||||||
:scroll="options.scroll"
|
:scroll="options.scroll"
|
||||||
:column-resizable="options.resizable"
|
:column-resizable="options.resizable"
|
||||||
@@ -131,8 +165,8 @@
|
|||||||
:row-class="options.rowClass"
|
:row-class="options.rowClass"
|
||||||
:hide-expand-button-on-empty="options.hideExpandButtonOnEmpty"
|
:hide-expand-button-on-empty="options.hideExpandButtonOnEmpty"
|
||||||
:default-expand-all-rows="options.expandAllRows"
|
:default-expand-all-rows="options.expandAllRows"
|
||||||
:summary="options.customerSummary || __summary || options.showSummary"
|
:summary="(options.customerSummary || options.showSummary) && __summary"
|
||||||
@selection-change="setSelecteds"
|
v-model:selectedKeys="selecteds"
|
||||||
@sorter-change="handlerSort"
|
@sorter-change="handlerSort"
|
||||||
>
|
>
|
||||||
<template #tr="{ record }">
|
<template #tr="{ record }">
|
||||||
@@ -155,7 +189,7 @@
|
|||||||
<ma-column
|
<ma-column
|
||||||
ref="crudColumnRef"
|
ref="crudColumnRef"
|
||||||
v-if="reloadColumn"
|
v-if="reloadColumn"
|
||||||
:columns="props.columns"
|
:columns="columns"
|
||||||
:isRecovery="isRecovery"
|
:isRecovery="isRecovery"
|
||||||
:crudFormRef="crudFormRef"
|
:crudFormRef="crudFormRef"
|
||||||
@refresh="() => refresh()"
|
@refresh="() => refresh()"
|
||||||
@@ -174,7 +208,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template
|
<template
|
||||||
v-for="(slot, slotIndex) in slots"
|
v-for="(slot, index) in getTitleSlot(columns)"
|
||||||
|
#[slot]="{ column }"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<slot :name="`${slot}`" v-bind="{ column }" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template
|
||||||
|
v-for="(slot, slotIndex) in getSlot(columns)"
|
||||||
:key="slotIndex"
|
:key="slotIndex"
|
||||||
#[slot]="{ record, column, rowIndex }"
|
#[slot]="{ record, column, rowIndex }"
|
||||||
>
|
>
|
||||||
@@ -213,19 +255,24 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ma-setting ref="crudSettingRef" />
|
<ma-setting ref="crudSettingRef" @onChangeSearchHide="initSearchColumns()" @onChangeColumnHide="changeColumn" />
|
||||||
|
<!-- 修改源码:透传ma-crud属性给ma-form -->
|
||||||
<ma-form ref="crudFormRef" @success="requestSuccess" v-bind="$attrs">
|
<ma-form ref="crudFormRef" @success="requestSuccess" v-bind="$attrs">
|
||||||
<template v-for="slot in Object.keys($slots)" #[slot]="component">
|
<template v-for="(slot, index) in Object.keys($slots)" #[slot]="component" :key="index">
|
||||||
<slot :name="slot" v-bind="component" />
|
<slot :name="slot" v-bind="component" />
|
||||||
</template>
|
</template>
|
||||||
</ma-form>
|
</ma-form>
|
||||||
|
|
||||||
<ma-import ref="crudImportRef" />
|
<ma-import ref="crudImportRef" @success="refresh" />
|
||||||
|
|
||||||
<ma-context-menu ref="crudContextMenuRef" @execCommand="execContextMenuCommand" />
|
<ma-context-menu ref="crudContextMenuRef" @execCommand="execContextMenuCommand" />
|
||||||
|
|
||||||
<a-image-preview :src="imgUrl" v-model:visible="imgVisible" />
|
<a-image-preview-group
|
||||||
|
:srcList="imgUrl"
|
||||||
|
v-model:visible="imgVisible"
|
||||||
|
v-if="typeof imgUrl === 'object' && imgUrl !== null"
|
||||||
|
/>
|
||||||
|
<a-image-preview :src="imgUrl" v-model:visible="imgVisible" v-else />
|
||||||
</a-layout-content>
|
</a-layout-content>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -234,7 +281,7 @@ import config from "@/config/crud"
|
|||||||
import { ref, watch, provide, nextTick, onMounted, onUnmounted } from "vue"
|
import { ref, watch, provide, nextTick, onMounted, onUnmounted } from "vue"
|
||||||
import defaultOptions from "./js/defaultOptions"
|
import defaultOptions from "./js/defaultOptions"
|
||||||
import { loadDict } from "@cps/ma-form/js/networkRequest.js"
|
import { loadDict } from "@cps/ma-form/js/networkRequest.js"
|
||||||
import ColumnService from "./js/columnService"
|
import ColumnService from "@cps/ma-form/js/columnService"
|
||||||
|
|
||||||
import MaSearch from "./components/search.vue"
|
import MaSearch from "./components/search.vue"
|
||||||
import MaForm from "./components/form.vue"
|
import MaForm from "./components/form.vue"
|
||||||
@@ -242,12 +289,14 @@ import MaSetting from "./components/setting.vue"
|
|||||||
import MaImport from "./components/import.vue"
|
import MaImport from "./components/import.vue"
|
||||||
import MaColumn from "./components/column.vue"
|
import MaColumn from "./components/column.vue"
|
||||||
import MaContextMenu from "./components/contextMenu.vue"
|
import MaContextMenu from "./components/contextMenu.vue"
|
||||||
|
import checkAuth from "@/directives/auth/auth"
|
||||||
|
import checkRole from "@/directives/role/role"
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
import { request } from "@/utils/request"
|
import { request } from "@/utils/request"
|
||||||
import tool from "@/utils/tool"
|
import tool from "@/utils/tool"
|
||||||
import Print from "@/utils/print"
|
import Print from "@/utils/print"
|
||||||
import { isArray, isFunction, isObject, isUndefined } from "lodash"
|
import { isArray, isFunction, isObject, isUndefined } from "lodash-es"
|
||||||
import { maEvent } from "@cps/ma-form/js/formItemMixin.js"
|
import { runEvent } from "@cps/ma-form/js/event.js"
|
||||||
import globalColumn from "@/config/column.js"
|
import globalColumn from "@/config/column.js"
|
||||||
import { useFormStore } from "@/store/index"
|
import { useFormStore } from "@/store/index"
|
||||||
|
|
||||||
@@ -267,6 +316,7 @@ const dicts = ref({})
|
|||||||
const cascaders = ref([])
|
const cascaders = ref([])
|
||||||
|
|
||||||
const reloadColumn = ref(true)
|
const reloadColumn = ref(true)
|
||||||
|
const tableIsShow = ref(true)
|
||||||
const openPagination = ref(false)
|
const openPagination = ref(false)
|
||||||
const imgVisible = ref(false)
|
const imgVisible = ref(false)
|
||||||
const imgUrl = ref(import.meta.env.VITE_APP_BASE + "not-image.png")
|
const imgUrl = ref(import.meta.env.VITE_APP_BASE + "not-image.png")
|
||||||
@@ -305,19 +355,21 @@ const init = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 收集数据
|
// 收集数据
|
||||||
props.columns.map((item) => {
|
columns.value.map((item) => {
|
||||||
if (item.cascaderItem && item.cascaderItem.length > 0) {
|
if (item.cascaderItem && item.cascaderItem.length > 0) {
|
||||||
cascaders.value.push(...item.cascaderItem)
|
cascaders.value.push(...item.cascaderItem)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
await props.columns.map(async (item) => {
|
await columns.value.map(async (item) => {
|
||||||
// 字典
|
// 字典
|
||||||
if (!cascaders.value.includes(item.dataIndex) && item.dict) {
|
if (!cascaders.value.includes(item.dataIndex) && item.dict) {
|
||||||
await loadDict(dicts.value, item)
|
await loadDict(dicts.value, item)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
await tabsHandler()
|
setTimeout(async () => {
|
||||||
|
await tabsHandler()
|
||||||
|
}, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
const dictTrans = (dataIndex, value) => {
|
const dictTrans = (dataIndex, value) => {
|
||||||
@@ -343,14 +395,14 @@ columns.value.map((item, index) => {
|
|||||||
item = columns.value[index]
|
item = columns.value[index]
|
||||||
}
|
}
|
||||||
!item.width && (item.width = options.value.columnWidth)
|
!item.width && (item.width = options.value.columnWidth)
|
||||||
|
!item.minWidth && (item.minWidth = options.value.columnMinWidth)
|
||||||
})
|
})
|
||||||
|
|
||||||
provide("options", options.value)
|
provide("options", options.value)
|
||||||
provide("columns", props.columns)
|
|
||||||
provide("layout", props.layout)
|
|
||||||
provide("dicts", dicts.value)
|
|
||||||
provide("dictColors", dictColors.value)
|
|
||||||
provide("requestParams", requestParams.value)
|
provide("requestParams", requestParams.value)
|
||||||
|
provide("columns", columns)
|
||||||
|
provide("dicts", dicts)
|
||||||
|
provide("layout", props.layout)
|
||||||
provide("dictTrans", dictTrans)
|
provide("dictTrans", dictTrans)
|
||||||
provide("dictColors", dictColors)
|
provide("dictColors", dictColors)
|
||||||
provide("isRecovery", isRecovery)
|
provide("isRecovery", isRecovery)
|
||||||
@@ -365,10 +417,7 @@ watch(
|
|||||||
(vl) => (options.value.api = vl)
|
(vl) => (options.value.api = vl)
|
||||||
)
|
)
|
||||||
|
|
||||||
watch(
|
watch([() => openPagination.value, () => total.value], () => options.value.pageLayout === "fixed" && settingFixedPage())
|
||||||
() => openPagination.value,
|
|
||||||
() => options.value.pageLayout === "fixed" && settingFixedPage()
|
|
||||||
)
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => formStore.crudList[options.value.id],
|
() => formStore.crudList[options.value.id],
|
||||||
@@ -378,6 +427,11 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const showImage = (url) => {
|
||||||
|
imgUrl.value = url
|
||||||
|
imgVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
const getSlot = (cls = []) => {
|
const getSlot = (cls = []) => {
|
||||||
let sls = []
|
let sls = []
|
||||||
cls.map((item) => {
|
cls.map((item) => {
|
||||||
@@ -391,14 +445,22 @@ const getSlot = (cls = []) => {
|
|||||||
return sls
|
return sls
|
||||||
}
|
}
|
||||||
|
|
||||||
const showImage = (url) => {
|
const getTitleSlot = (cls = []) => {
|
||||||
imgUrl.value = url
|
let sls = []
|
||||||
imgVisible.value = true
|
cls.map((item) => {
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
let tmp = getTitleSlot(item.children)
|
||||||
|
sls.push(...tmp)
|
||||||
|
} else if (item.dataIndex) {
|
||||||
|
sls.push(`tableTitle-${item.dataIndex}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return sls
|
||||||
}
|
}
|
||||||
|
|
||||||
const getSearchSlot = () => {
|
const getSearchSlot = () => {
|
||||||
let sls = []
|
let sls = []
|
||||||
props.columns.map((item) => {
|
columns.value.map((item) => {
|
||||||
if (item.search && item.search === true) {
|
if (item.search && item.search === true) {
|
||||||
sls.push(item.dataIndex)
|
sls.push(item.dataIndex)
|
||||||
}
|
}
|
||||||
@@ -406,9 +468,6 @@ const getSearchSlot = () => {
|
|||||||
return sls
|
return sls
|
||||||
}
|
}
|
||||||
|
|
||||||
slots.value = getSlot(props.columns)
|
|
||||||
searchSlots.value = getSearchSlot(props.columns)
|
|
||||||
|
|
||||||
const requestData = async () => {
|
const requestData = async () => {
|
||||||
await init()
|
await init()
|
||||||
if (options.value.showIndex && columns.value.length > 0 && columns.value[0].dataIndex !== "__index") {
|
if (options.value.showIndex && columns.value.length > 0 && columns.value[0].dataIndex !== "__index") {
|
||||||
@@ -456,6 +515,7 @@ const requestHandle = async () => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
isFunction(options.value.beforeRequest) && options.value.beforeRequest(requestParams.value)
|
isFunction(options.value.beforeRequest) && options.value.beforeRequest(requestParams.value)
|
||||||
if (isFunction(currentApi.value)) {
|
if (isFunction(currentApi.value)) {
|
||||||
|
// 修改源码:添加options.prameters参数
|
||||||
if (options.value.parameters) {
|
if (options.value.parameters) {
|
||||||
requestParams.value = { ...requestParams.value, ...options.value.parameters }
|
requestParams.value = { ...requestParams.value, ...options.value.parameters }
|
||||||
}
|
}
|
||||||
@@ -463,7 +523,6 @@ const requestHandle = async () => {
|
|||||||
if (response.rows) {
|
if (response.rows) {
|
||||||
tableData.value = response.rows
|
tableData.value = response.rows
|
||||||
if (response.pageInfo) {
|
if (response.pageInfo) {
|
||||||
// 这里去找total字段
|
|
||||||
total.value = response.pageInfo.total
|
total.value = response.pageInfo.total
|
||||||
openPagination.value = true
|
openPagination.value = true
|
||||||
} else {
|
} else {
|
||||||
@@ -473,9 +532,9 @@ const requestHandle = async () => {
|
|||||||
tableData.value = response
|
tableData.value = response
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error(`ma-crud error:crud.api 不是一个 Function.`)
|
console.error(`ma-crud error:您传递的api属性不是一个函数.`)
|
||||||
}
|
}
|
||||||
isFunction(options.value.afterRequest) && options.value.afterRequest(tableData.value)
|
isFunction(options.value.afterRequest) && (tableData.value = options.value.afterRequest(tableData.value))
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,6 +556,8 @@ const refresh = async () => {
|
|||||||
: options.value.api
|
: options.value.api
|
||||||
await requestHandle()
|
await requestHandle()
|
||||||
}
|
}
|
||||||
|
selecteds.value = []
|
||||||
|
tableRef.value.selectAll(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchSubmitHandler = async (formData) => {
|
const searchSubmitHandler = async (formData) => {
|
||||||
@@ -544,7 +605,11 @@ const toggleSearch = async () => {
|
|||||||
|
|
||||||
const settingFixedPage = () => {
|
const settingFixedPage = () => {
|
||||||
const workAreaHeight = document.querySelector(".work-area").offsetHeight
|
const workAreaHeight = document.querySelector(".work-area").offsetHeight
|
||||||
const tableHeight = workAreaHeight - headerHeight.value - (openPagination.value ? 152 : 108)
|
const tableHeight =
|
||||||
|
workAreaHeight -
|
||||||
|
headerHeight.value -
|
||||||
|
(openPagination.value ? 160 : 116) +
|
||||||
|
(total.value === 0 && !loading.value ? 44 : 0)
|
||||||
crudContentRef.value.style.height = tableHeight + "px"
|
crudContentRef.value.style.height = tableHeight + "px"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,9 +657,17 @@ const dbClickOpenEdit = (record) => {
|
|||||||
Message.error("回收站数据不可编辑")
|
Message.error("回收站数据不可编辑")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (isArray(options.value.edit.auth) || options.value.edit.auth === undefined) {
|
||||||
|
for (let index in options.value.edit.auth) {
|
||||||
|
if (!checkAuth(options.value.edit.auth[index])) {
|
||||||
|
Message.error("没有编辑数据的权限")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options.value.edit.api && isFunction(options.value.edit.api)) {
|
if (options.value.edit.api && options.value.edit.show && isFunction(options.value.edit.api)) {
|
||||||
editAction(record)
|
editAction(record)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -630,6 +703,7 @@ const deletesMultipleAction = async () => {
|
|||||||
options.value.afterDelete(response)
|
options.value.afterDelete(response)
|
||||||
}
|
}
|
||||||
response.success && Message.success(response.message || `删除成功!`)
|
response.success && Message.success(response.message || `删除成功!`)
|
||||||
|
selecteds.value = []
|
||||||
await refresh()
|
await refresh()
|
||||||
} else {
|
} else {
|
||||||
Message.error("至少选择一条数据")
|
Message.error("至少选择一条数据")
|
||||||
@@ -640,6 +714,7 @@ const recoverysMultipleAction = async () => {
|
|||||||
if (selecteds.value && selecteds.value.length > 0) {
|
if (selecteds.value && selecteds.value.length > 0) {
|
||||||
const response = await options.value.recovery.api({ ids: selecteds.value })
|
const response = await options.value.recovery.api({ ids: selecteds.value })
|
||||||
response.success && Message.success(response.message || `恢复成功!`)
|
response.success && Message.success(response.message || `恢复成功!`)
|
||||||
|
selecteds.value = []
|
||||||
await refresh()
|
await refresh()
|
||||||
} else {
|
} else {
|
||||||
Message.error("至少选择一条数据")
|
Message.error("至少选择一条数据")
|
||||||
@@ -690,24 +765,30 @@ const __summary = ({ data }) => {
|
|||||||
let summarySuffixText = {}
|
let summarySuffixText = {}
|
||||||
let length = data.length || 0
|
let length = data.length || 0
|
||||||
summary.map((item) => {
|
summary.map((item) => {
|
||||||
summaryData[item.dataIndex] = 0
|
if (item.action && item.action === "text") {
|
||||||
summaryPrefixText[item.dataIndex] = item?.prefixText ?? ""
|
summaryData[item.dataIndex] = item.content
|
||||||
summarySuffixText[item.dataIndex] = item?.suffixText ?? ""
|
} else {
|
||||||
data.map((record) => {
|
summaryData[item.dataIndex] = 0
|
||||||
if (record[item.dataIndex]) {
|
summaryPrefixText[item.dataIndex] = item?.prefixText ?? ""
|
||||||
if (item.action && item.action === "sum") {
|
summarySuffixText[item.dataIndex] = item?.suffixText ?? ""
|
||||||
summaryData[item.dataIndex] += parseFloat(record[item.dataIndex])
|
data.map((record) => {
|
||||||
|
if (record[item.dataIndex]) {
|
||||||
|
if (item.action && item.action === "sum") {
|
||||||
|
summaryData[item.dataIndex] += parseFloat(record[item.dataIndex])
|
||||||
|
}
|
||||||
|
if (item.action && item.action === "avg") {
|
||||||
|
summaryData[item.dataIndex] += parseFloat(record[item.dataIndex]) / length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (item.action && item.action === "avg") {
|
})
|
||||||
summaryData[item.dataIndex] += parseFloat(record[item.dataIndex]) / length
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
for (let i in summaryData) {
|
for (let i in summaryData) {
|
||||||
summaryData[i] =
|
if (/^\d+(\.\d+)?$/.test(summaryData[i])) {
|
||||||
summaryPrefixText[i] + tool.groupSeparator(summaryData[i].toFixed(2)) + summarySuffixText[i]
|
summaryData[i] =
|
||||||
|
summaryPrefixText[i] + tool.groupSeparator(summaryData[i].toFixed(2)) + summarySuffixText[i]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [summaryData]
|
return [summaryData]
|
||||||
@@ -724,7 +805,7 @@ const tabChange = async (value) => {
|
|||||||
const params = {}
|
const params = {}
|
||||||
params[searchKey] = value
|
params[searchKey] = value
|
||||||
requestParams.value = Object.assign(requestParams.value, params)
|
requestParams.value = Object.assign(requestParams.value, params)
|
||||||
await maEvent.customeEvent(options.value.tabs, value, "onChange")
|
await runEvent(options.value.tabs, "onChange", undefined, value)
|
||||||
await refresh()
|
await refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,7 +837,7 @@ const execContextMenuCommand = async (args) => {
|
|||||||
crudColumnRef.value.deleteAction(record)
|
crudColumnRef.value.deleteAction(record)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
await maEvent.customeEvent(item, args, "onCommand")
|
await runEvent(item, "onCommand", undefined, args)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -767,26 +848,33 @@ const tabsHandler = async () => {
|
|||||||
if (isFunction(tabs.data) || isArray(tabs.data)) {
|
if (isFunction(tabs.data) || isArray(tabs.data)) {
|
||||||
tabs.data = isFunction(tabs.data) ? await tabs.data() : tabs.data
|
tabs.data = isFunction(tabs.data) ? await tabs.data() : tabs.data
|
||||||
} else if (!isUndefined(tabs.dataIndex)) {
|
} else if (!isUndefined(tabs.dataIndex)) {
|
||||||
const col = props.columns.find((item) => item.dataIndex === tabs.dataIndex)
|
const col = columns.value.find((item) => item.dataIndex === tabs.dataIndex)
|
||||||
if (col.search === true && isObject(col.dict)) {
|
if (col.search === true && isObject(col.dict)) {
|
||||||
tabs.data = dicts.value[tabs.dataIndex]
|
tabs.data = dicts.value[tabs.dataIndex]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
const isBatch = (obj) => (isUndefined(obj) ? true : (obj?.batch ?? true))
|
||||||
if (typeof options.value.autoRequest == "undefined" || options.value.autoRequest) {
|
|
||||||
await requestData()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const changeColumn = async () => {
|
||||||
|
tableIsShow.value = false
|
||||||
|
await nextTick(() => (tableIsShow.value = true))
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
if (!options.value.expandSearch && crudSearchRef.value) {
|
if (!options.value.expandSearch && crudSearchRef.value) {
|
||||||
crudSearchRef.value.setSearchHidden()
|
crudSearchRef.value.setSearchHidden()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.value.pageLayout === "fixed") {
|
if (options.value.pageLayout === "fixed") {
|
||||||
window.addEventListener("resize", resizeHandler, false)
|
await nextTick(() => {
|
||||||
headerHeight.value = crudHeaderRef.value.offsetHeight
|
window.addEventListener("resize", resizeHandler, false)
|
||||||
settingFixedPage()
|
headerHeight.value = crudHeaderRef.value.offsetHeight
|
||||||
|
settingFixedPage()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (typeof options.value.autoRequest == "undefined" || options.value.autoRequest) {
|
||||||
|
await requestData()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -803,6 +891,11 @@ const getFormColumns = async (type = "add") => {
|
|||||||
return await crudFormRef.value.getFormColumns(type)
|
return await crudFormRef.value.getFormColumns(type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getCurrentPage = () => requestParams.value[config.request.page]
|
||||||
|
const getPageSize = () => requestParams.value[config.request.pageSize]
|
||||||
|
const getTotal = () => total.value
|
||||||
|
const initSearchColumns = () => crudSearchRef.value.initSearchColumns()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取column属性服务类
|
* 获取column属性服务类
|
||||||
* @returns ColumnService
|
* @returns ColumnService
|
||||||
@@ -810,7 +903,7 @@ const getFormColumns = async (type = "add") => {
|
|||||||
const getColumnService = (strictMode = true) => {
|
const getColumnService = (strictMode = true) => {
|
||||||
return new ColumnService({ columns: columns.value, cascaders: cascaders.value, dicts: dicts.value }, strictMode)
|
return new ColumnService({ columns: columns.value, cascaders: cascaders.value, dicts: dicts.value }, strictMode)
|
||||||
}
|
}
|
||||||
|
const setTableData = (data = []) => (tableData.value = data)
|
||||||
defineExpose({
|
defineExpose({
|
||||||
refresh,
|
refresh,
|
||||||
requestData,
|
requestData,
|
||||||
@@ -822,13 +915,18 @@ defineExpose({
|
|||||||
getFormData,
|
getFormData,
|
||||||
getFormColumns,
|
getFormColumns,
|
||||||
getColumnService,
|
getColumnService,
|
||||||
|
getCurrentPage,
|
||||||
|
getPageSize,
|
||||||
|
getTotal,
|
||||||
requestParams,
|
requestParams,
|
||||||
isRecovery,
|
isRecovery,
|
||||||
tableRef,
|
tableRef,
|
||||||
|
initSearchColumns,
|
||||||
crudFormRef,
|
crudFormRef,
|
||||||
crudSearchRef,
|
crudSearchRef,
|
||||||
crudImportRef,
|
crudImportRef,
|
||||||
crudSettingRef
|
crudSettingRef,
|
||||||
|
setTableData
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -840,6 +938,5 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
._crud-footer {
|
._crud-footer {
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
height: 80px;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ import { loadDict } from "@cps/ma-form/js/networkRequest"
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* columnService 列服务处理类
|
* columnService 列服务处理类
|
||||||
* 首先感谢 @NEKGod 提交的PR,此功能原本写在了 Ma-Crud 组件,我特意摘出来,封装成类通过引用来调用
|
|
||||||
* @author NEKGod, X.Mo <root@imoi.cn>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const objectService = function (item) {
|
const objectService = function (item) {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export default {
|
|||||||
// 是否显示总结行
|
// 是否显示总结行
|
||||||
showSummary: false,
|
showSummary: false,
|
||||||
// 自定义总结行,要传入函数
|
// 自定义总结行,要传入函数
|
||||||
customerSummary: false,
|
customerSummary: undefined,
|
||||||
// 是否显示工具栏
|
// 是否显示工具栏
|
||||||
showTools: true,
|
showTools: true,
|
||||||
// 表头是否吸顶
|
// 表头是否吸顶
|
||||||
@@ -54,7 +54,8 @@ export default {
|
|||||||
// 页面布局方式,支持 normal(标准)和 fixed(固定)两种
|
// 页面布局方式,支持 normal(标准)和 fixed(固定)两种
|
||||||
pageLayout: "normal",
|
pageLayout: "normal",
|
||||||
// 默认统一设置列宽度
|
// 默认统一设置列宽度
|
||||||
columnWidth: 100,
|
columnWidth: 0, // 列宽更新为最小列宽(此处设置为 0 时候,默认最小列宽生效)
|
||||||
|
columnMinWidth: 100,
|
||||||
// 搜索标签对齐方式
|
// 搜索标签对齐方式
|
||||||
searchLabelAlign: "right",
|
searchLabelAlign: "right",
|
||||||
// 全局搜索标签宽度
|
// 全局搜索标签宽度
|
||||||
@@ -159,7 +160,13 @@ export default {
|
|||||||
// 按钮文案
|
// 按钮文案
|
||||||
text: "编辑",
|
text: "编辑",
|
||||||
// 是否显示
|
// 是否显示
|
||||||
show: false
|
show: false,
|
||||||
|
// 数据来源:table(表格行数据) | api(通过接口获取数据)
|
||||||
|
dataSource: "table",
|
||||||
|
// 数据源API接口
|
||||||
|
dataSourceApi: undefined,
|
||||||
|
// 是否禁用,仅表格行内按钮有效
|
||||||
|
disabled: false
|
||||||
},
|
},
|
||||||
delete: {
|
delete: {
|
||||||
// 删除api
|
// 删除api
|
||||||
@@ -170,6 +177,8 @@ export default {
|
|||||||
role: [],
|
role: [],
|
||||||
// 按钮文案
|
// 按钮文案
|
||||||
text: "删除",
|
text: "删除",
|
||||||
|
// 是否禁用,仅表格行内按钮有效
|
||||||
|
disabled: false,
|
||||||
|
|
||||||
// 真实删除api
|
// 真实删除api
|
||||||
realApi: undefined,
|
realApi: undefined,
|
||||||
@@ -179,9 +188,13 @@ export default {
|
|||||||
realRole: [],
|
realRole: [],
|
||||||
// 真实按钮文案
|
// 真实按钮文案
|
||||||
realText: "删除",
|
realText: "删除",
|
||||||
|
// 真实删除是否禁用,仅表格行内按钮有效
|
||||||
|
realDisabled: false,
|
||||||
|
|
||||||
// 是否显示
|
// 是否显示
|
||||||
show: false
|
show: false,
|
||||||
|
// 是否显示批量处理按钮
|
||||||
|
batch: true
|
||||||
},
|
},
|
||||||
recovery: {
|
recovery: {
|
||||||
// 恢复api
|
// 恢复api
|
||||||
@@ -193,18 +206,26 @@ export default {
|
|||||||
// 按钮文案
|
// 按钮文案
|
||||||
text: "恢复",
|
text: "恢复",
|
||||||
// 是否显示
|
// 是否显示
|
||||||
show: false
|
show: false,
|
||||||
|
// 是否显示批量处理按钮
|
||||||
|
batch: true
|
||||||
|
},
|
||||||
|
see: {
|
||||||
|
// 显示查看按钮的权限
|
||||||
|
auth: [],
|
||||||
|
// 显示查看按钮的角色
|
||||||
|
role: [],
|
||||||
|
// 按钮文案
|
||||||
|
text: "查看",
|
||||||
|
// 是否显示
|
||||||
|
show: false,
|
||||||
|
// 数据来源:table(表格行数据) | api(通过接口获取数据)
|
||||||
|
dataSource: "table",
|
||||||
|
// 数据源API接口
|
||||||
|
dataSourceApi: undefined,
|
||||||
|
// 是否禁用,仅表格行内按钮有效
|
||||||
|
disabled: false
|
||||||
},
|
},
|
||||||
// see: {
|
|
||||||
// // 显示查看按钮的权限
|
|
||||||
// auth: [],
|
|
||||||
// // 显示查看按钮的角色
|
|
||||||
// role: [],
|
|
||||||
// // 按钮文案
|
|
||||||
// text: '查看',
|
|
||||||
// // 是否显示
|
|
||||||
// show: false,
|
|
||||||
// },
|
|
||||||
import: {
|
import: {
|
||||||
// 导入url
|
// 导入url
|
||||||
url: undefined,
|
url: undefined,
|
||||||
|
|||||||
@@ -1,116 +1,133 @@
|
|||||||
import { VNodeChild } from "vue"
|
import { VNodeChild,Ref } from "vue";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单组件类型
|
* 表单组件类型
|
||||||
*/
|
*/
|
||||||
import { FieldRule } from "@arco-design/web-vue"
|
import { FieldRule } from "@arco-design/web-vue";
|
||||||
|
|
||||||
|
export type FormDataType =
|
||||||
|
| "radio"
|
||||||
|
| "checkbox"
|
||||||
|
| "select"
|
||||||
|
| "transfer"
|
||||||
|
| "tree-select"
|
||||||
|
| "cascader"
|
||||||
|
| "date"
|
||||||
|
| "month"
|
||||||
|
| "year"
|
||||||
|
| "week"
|
||||||
|
| "quarter"
|
||||||
|
| "range"
|
||||||
|
| "time"
|
||||||
|
| "input"
|
||||||
|
| "password"
|
||||||
|
| "textarea"
|
||||||
|
| "upload"
|
||||||
|
| "select-user"
|
||||||
|
| "editor"
|
||||||
|
| "icon"
|
||||||
|
| "user-info"
|
||||||
|
| "city-linkage"
|
||||||
|
| "form-group"
|
||||||
|
| "select-resource"
|
||||||
|
| 'component';
|
||||||
|
|
||||||
export type FormDateType =
|
|
||||||
| "radio"
|
|
||||||
| "checkbox"
|
|
||||||
| "select"
|
|
||||||
| "transfer"
|
|
||||||
| "tree-select"
|
|
||||||
| "cascader"
|
|
||||||
| "date"
|
|
||||||
| "month"
|
|
||||||
| "year"
|
|
||||||
| "week"
|
|
||||||
| "quarter"
|
|
||||||
| "range"
|
|
||||||
| "time"
|
|
||||||
| "input"
|
|
||||||
| "password"
|
|
||||||
| "textarea"
|
|
||||||
| "upload"
|
|
||||||
| "select-user"
|
|
||||||
| "editor"
|
|
||||||
| "code-editor"
|
|
||||||
| "icon"
|
|
||||||
| "user-info"
|
|
||||||
| "city-linkage"
|
|
||||||
| "form-group"
|
|
||||||
| "select-resource"
|
|
||||||
/**
|
/**
|
||||||
* 列字典
|
* 列字典
|
||||||
*/
|
*/
|
||||||
export interface ColumnDict {
|
export interface ColumnDict {
|
||||||
// 字典名称,快捷查询字典接口查询
|
// 字典名称,快捷查询字典接口查询
|
||||||
name?: string
|
name?: string;
|
||||||
// 自定义url查询
|
// 自定义url查询
|
||||||
url?: string
|
url?: string;
|
||||||
// url查询方法,填写url之后生效
|
// url查询方法,填写url之后生效
|
||||||
method?: "GET" | "POST" | "PUT" | "DELETE"
|
method?: "GET" | "POST" | "PUT" | "DELETE";
|
||||||
// url查询params数据,填写url之后生效
|
// url查询params数据,填写url之后生效
|
||||||
params?: object
|
params?: object;
|
||||||
// url查询body数据,填写url之后生效
|
// url查询body数据,填写url之后生效
|
||||||
body?: object
|
body?: object;
|
||||||
// 直接设置字典值
|
// 直接设置字典值
|
||||||
data?: object | Function
|
data?: object | Function;
|
||||||
// 表格列的值是否翻译为字典对应标签
|
// 表格列的值是否翻译为字典对应标签
|
||||||
translation?: boolean
|
translation?: boolean;
|
||||||
// 表格key 和 value的props设置
|
// 表格key 和 value的props设置
|
||||||
props?: {
|
props?: {
|
||||||
label?: string
|
label?: string;
|
||||||
value?: string
|
value?: string;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BasicColumn {
|
export interface BasicColumn {
|
||||||
// 标题
|
// 标题
|
||||||
title: string
|
title: string;
|
||||||
// 字段名称
|
// 字段名称
|
||||||
dataIndex: string
|
dataIndex: string;
|
||||||
// 组件类型
|
// 组件类型
|
||||||
formType?: FormDateType
|
formType?: FormDataType;
|
||||||
// 表格列对齐方式
|
// 表格列对齐方式
|
||||||
align?: "center" | "right" | "left"
|
align?: "center" | "right" | "left";
|
||||||
// 字段是否加入搜索
|
// 字段是否加入搜索
|
||||||
search?: boolean
|
search?: boolean;
|
||||||
// 列宽
|
// 列宽
|
||||||
width?: number | "auto"
|
width?: number | "auto";
|
||||||
// 表格列是否隐藏
|
// 表格列是否隐藏
|
||||||
hide?: boolean
|
hide?: boolean;
|
||||||
// 编辑|创建 通用是否显示字段
|
// 编辑|创建 通用是否显示字段
|
||||||
display?: boolean
|
display?: boolean;
|
||||||
// 添加弹窗是否显示字段
|
// 添加弹窗是否显示字段
|
||||||
addDisplay?: boolean
|
addDisplay?: boolean | (() => boolean);
|
||||||
// 编辑弹窗是否显示字段
|
// 编辑弹窗是否显示字段
|
||||||
editDisplay?: boolean
|
editDisplay?: boolean | ((record) => boolean);
|
||||||
// 编辑|创建 通用是否禁用字段
|
// 编辑|创建 通用是否禁用字段
|
||||||
disabled?: boolean
|
disabled?: boolean;
|
||||||
// 添加弹窗是否禁用字段
|
// 添加弹窗是否禁用字段
|
||||||
addDisabled?: boolean
|
addDisabled?: boolean | (() => boolean);
|
||||||
// 编辑弹窗是否禁用字段
|
// 编辑弹窗是否禁用字段
|
||||||
editDisabled?: boolean
|
editDisabled?: boolean | ((record) => boolean);
|
||||||
// 编辑|创建 通用是否只读字段
|
// 编辑|创建 通用是否只读字段
|
||||||
readonly?: boolean
|
readonly?: boolean;
|
||||||
// 添加弹窗是否只读字段
|
// 添加弹窗是否只读字段
|
||||||
addReadonly?: boolean
|
addReadonly?: boolean | (() => boolean);
|
||||||
// 编辑弹窗是否只读字段
|
// 编辑弹窗是否只读字段
|
||||||
editReadonly?: boolean
|
editReadonly?: boolean | ((record) => boolean);
|
||||||
// 自定义渲染
|
// 自定义渲染
|
||||||
customRender?: (({ record, column, rowIndex }) => VNodeChild | JSX.Element) | VNodeChild | JSX.Element
|
customRender?:
|
||||||
// 字段新增时默认值
|
| (({ record, column, rowIndex }) => VNodeChild | JSX.Element)
|
||||||
addDefaultValue?: number | string | boolean | undefined | ((record) => number | string | boolean | undefined)
|
| VNodeChild
|
||||||
// 字段编辑时默认值
|
| JSX.Element;
|
||||||
editDefaultValue?: number | string | boolean | undefined | ((record) => number | string | boolean | undefined)
|
// 字段新增时默认值
|
||||||
// select,radio,treeSelect,下拉字典配置
|
addDefaultValue?:
|
||||||
dict?: ColumnDict
|
| number
|
||||||
// 继承公用配置
|
| string
|
||||||
common?: boolean
|
| boolean
|
||||||
// select 和 tree-select 组件是否开启虚拟列表
|
| undefined
|
||||||
virtualList?: boolean
|
| ((record) => number | string | boolean | undefined);
|
||||||
// 搜索默认值
|
// 字段编辑时默认值
|
||||||
searchDefaultValue?: number | string | undefined
|
editDefaultValue?:
|
||||||
// 搜索描述
|
| number
|
||||||
searchPlaceholder?: string
|
| string
|
||||||
//编辑|创建 通用规则
|
| boolean
|
||||||
commonRules?: FieldRule | FieldRule[]
|
| undefined
|
||||||
// 创建时规则
|
| ((record) => number | string | boolean | undefined);
|
||||||
addRules?: FieldRule | FieldRule[]
|
// select,radio,treeSelect,下拉字典配置
|
||||||
// 编辑时规则
|
dict?: ColumnDict;
|
||||||
editRules?: FieldRule | FieldRule[]
|
// 继承公用配置
|
||||||
// 子表单数据
|
common?: boolean;
|
||||||
children?: BasicColumn[]
|
// select 和 tree-select 组件是否开启虚拟列表
|
||||||
|
virtualList?: boolean;
|
||||||
|
// 搜索默认值
|
||||||
|
searchDefaultValue?: number | string | undefined;
|
||||||
|
// 搜索描述
|
||||||
|
searchPlaceholder?: string;
|
||||||
|
// 表格是否快捷编辑,只支持 input date select
|
||||||
|
quickEdit?: boolean;
|
||||||
|
component?:Ref;
|
||||||
|
//编辑|创建 通用规则
|
||||||
|
commonRules?: FieldRule | FieldRule[];
|
||||||
|
// 创建时规则
|
||||||
|
addRules?: FieldRule | FieldRule[];
|
||||||
|
// 编辑时规则
|
||||||
|
editRules?: FieldRule | FieldRule[];
|
||||||
|
// 子表单数据
|
||||||
|
children?: BasicColumn[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,189 +1,189 @@
|
|||||||
export interface BasicCrud {
|
export interface BasicCrud {
|
||||||
// 表格接口
|
// 表格接口
|
||||||
api?: undefined | any
|
api?: undefined | any;
|
||||||
// 主键名称
|
// 主键名称
|
||||||
pk?: string
|
pk?: string;
|
||||||
// 设置选择列
|
// 设置选择列
|
||||||
rowSelection?:
|
rowSelection?:
|
||||||
| undefined
|
| undefined
|
||||||
| {
|
| {
|
||||||
// 选择值的标识,默认id
|
// 选择值的标识,默认id
|
||||||
key?: string
|
key?: string;
|
||||||
// 选择列是否显示全选
|
// 选择列是否显示全选
|
||||||
showCheckedAll?: boolean
|
showCheckedAll?: boolean;
|
||||||
// 行选择器类型
|
// 行选择器类型
|
||||||
type?: "checkbox" | "radio"
|
type?: 'checkbox' | 'radio';
|
||||||
// 选择器列标题
|
// 选择器列标题
|
||||||
title?: string | "#"
|
title?: string | '#';
|
||||||
// 列宽度
|
// 列宽度
|
||||||
width?: number | 60
|
width?: number | 60;
|
||||||
// 是否固定
|
// 是否固定
|
||||||
fixed?: boolean | false
|
fixed?: boolean | false;
|
||||||
// 是否仅展示当前页的keys
|
// 是否仅展示当前页的keys
|
||||||
onlyCurrent?: boolean | true
|
onlyCurrent?: boolean | true;
|
||||||
}
|
};
|
||||||
// 搜索label宽度
|
// 搜索label宽度
|
||||||
searchLabelWidth?: string | "auto"
|
searchLabelWidth?: string | "auto";
|
||||||
// 搜索label对齐方式
|
// 搜索label对齐方式
|
||||||
searchLabelAlign?: "center" | "right" | "left"
|
searchLabelAlign?: "center" | "right" | "left";
|
||||||
// 一行多少列
|
// 一行多少列
|
||||||
searchLabelCols?: number
|
searchLabelCols?: number;
|
||||||
// 是否显示边框
|
// 是否显示边框
|
||||||
bordered?: { wrapper?: boolean; cell?: boolean }
|
bordered?: { wrapper?: boolean; cell?: boolean };
|
||||||
// 是否开启拖拽排序
|
// 是否开启拖拽排序
|
||||||
dragSort?: boolean
|
dragSort?: boolean;
|
||||||
// 子节点为空隐藏节点按钮
|
// 子节点为空隐藏节点按钮
|
||||||
hideExpandButtonOnEmpty?: boolean
|
hideExpandButtonOnEmpty?: boolean;
|
||||||
// 默认展开所有行
|
// 默认展开所有行
|
||||||
expandAllRows?: boolean
|
expandAllRows?: boolean;
|
||||||
// 斑马线
|
// 斑马线
|
||||||
stripe?: boolean
|
stripe?: boolean;
|
||||||
// 新增、编辑、删除完成后是否刷新表格
|
// 新增、编辑、删除完成后是否刷新表格
|
||||||
dataCompleteRefresh?: boolean
|
dataCompleteRefresh?: boolean;
|
||||||
// 表格大小
|
// 表格大小
|
||||||
size?: "mini" | "small" | "medium" | "large"
|
size?: "mini" | "small" | "medium" | "large";
|
||||||
// 是否开启双击编辑数据
|
// 是否开启双击编辑数据
|
||||||
isDbClickEdit?: boolean
|
isDbClickEdit?: boolean;
|
||||||
// 是否显示展开/折叠按钮
|
// 是否显示展开/折叠按钮
|
||||||
isExpand?: boolean
|
isExpand?: boolean;
|
||||||
// 是否显示自定义
|
// 是否显示自定义
|
||||||
showExpandRow?: boolean
|
showExpandRow?: boolean;
|
||||||
// 是否显示总结行
|
// 是否显示总结行
|
||||||
showSummary?: boolean
|
showSummary?: boolean;
|
||||||
// 自定义总结行,要传入函数
|
// 自定义总结行,要传入函数
|
||||||
customerSummary?: boolean
|
customerSummary?: boolean;
|
||||||
// 是否显示工具栏
|
// 是否显示工具栏
|
||||||
showTools?: boolean
|
showTools?: boolean;
|
||||||
// 新增和编辑显示设置
|
// 新增和编辑显示设置
|
||||||
formOption?: {
|
formOption?: {
|
||||||
// 显示方式支持模态框和抽屉?: modal drawer
|
// 显示方式支持模态框和抽屉?: modal drawer
|
||||||
viewType?: "modal" | "drawer"
|
viewType?: "modal" | "drawer";
|
||||||
// 显示宽度
|
// 显示宽度
|
||||||
width?: number
|
width?: number;
|
||||||
// 是否全屏,只有modal有效
|
// 是否全屏,只有modal有效
|
||||||
isFull?: boolean
|
isFull?: boolean;
|
||||||
}
|
};
|
||||||
//新增确定之前修改form值
|
//新增确定之前修改form值
|
||||||
beforeAdd?: (form) => void
|
beforeAdd?: (form) => void;
|
||||||
//新增确定之后调用,返回接口response和form值
|
//新增确定之后调用,返回接口response和form值
|
||||||
afterAdd?: (response, form) => void
|
afterAdd?: (response, form) => void;
|
||||||
//编辑确定之前修改form值
|
//编辑确定之前修改form值
|
||||||
beforeEdit?: (form) => void
|
beforeEdit?: (form) => void;
|
||||||
//编辑确定之后调用,返回接口response和form值
|
//编辑确定之后调用,返回接口response和form值
|
||||||
afterEdit?: (response, form) => void
|
afterEdit?: (response, form) => void;
|
||||||
add?: {
|
add?: {
|
||||||
// 新增api
|
// 新增api
|
||||||
api?: undefined | any
|
api?: undefined | any;
|
||||||
// 显示新增按钮的权限
|
// 显示新增按钮的权限
|
||||||
auth?: string[]
|
auth?: string[];
|
||||||
// 显示新增按钮的角色
|
// 显示新增按钮的角色
|
||||||
role?: string[]
|
role?: string[];
|
||||||
// 按钮文案
|
// 按钮文案
|
||||||
text?: string
|
text?: string;
|
||||||
// 是否显示
|
// 是否显示
|
||||||
show?: boolean
|
show?: boolean;
|
||||||
}
|
};
|
||||||
edit?: {
|
edit?: {
|
||||||
// 编辑api
|
// 编辑api
|
||||||
api?: undefined | any
|
api?: undefined | any;
|
||||||
// 显示编辑按钮的权限
|
// 显示编辑按钮的权限
|
||||||
auth?: string[]
|
auth?: string[];
|
||||||
// 显示编辑按钮的角色
|
// 显示编辑按钮的角色
|
||||||
role?: string[]
|
role?: string[];
|
||||||
// 按钮文案
|
// 按钮文案
|
||||||
text?: string
|
text?: string;
|
||||||
// 是否显示
|
// 是否显示
|
||||||
show?: boolean
|
show?: boolean;
|
||||||
}
|
};
|
||||||
delete?: {
|
delete?: {
|
||||||
// 删除api
|
// 删除api
|
||||||
api?: undefined | any
|
api?: undefined | any;
|
||||||
// 显示删除按钮的权限
|
// 显示删除按钮的权限
|
||||||
auth?: string[]
|
auth?: string[];
|
||||||
// 显示删除按钮的角色
|
// 显示删除按钮的角色
|
||||||
role?: string[]
|
role?: string[];
|
||||||
// 按钮文案
|
// 按钮文案
|
||||||
text?: string
|
text?: string;
|
||||||
|
|
||||||
// 真实删除api
|
// 真实删除api
|
||||||
realApi?: undefined | any
|
realApi?: undefined | any;
|
||||||
// 显示真实删除按钮的权限
|
// 显示真实删除按钮的权限
|
||||||
realAuth?: string[]
|
realAuth?: string[];
|
||||||
// 显示真实删除按钮的角色
|
// 显示真实删除按钮的角色
|
||||||
realRole?: string[]
|
realRole?: string[];
|
||||||
// 真实按钮文案
|
// 真实按钮文案
|
||||||
realText?: string
|
realText?: string;
|
||||||
|
|
||||||
// 是否显示
|
// 是否显示
|
||||||
show?: boolean
|
show?: boolean;
|
||||||
}
|
};
|
||||||
// Todo
|
// Todo
|
||||||
recycleApi?: any
|
recycleApi?: any;
|
||||||
recovery?: {
|
recovery?: {
|
||||||
// 显示恢复按钮的权限
|
// 显示恢复按钮的权限
|
||||||
auth?: string[]
|
auth?: string[];
|
||||||
// 显示恢复按钮的角色
|
// 显示恢复按钮的角色
|
||||||
role?: string[]
|
role?: string[];
|
||||||
// 按钮文案
|
// 按钮文案
|
||||||
text?: string
|
text?: string;
|
||||||
// 是否显示
|
// 是否显示
|
||||||
show?: boolean
|
show?: boolean;
|
||||||
// 恢复列表查询api
|
// 恢复列表查询api
|
||||||
api?: undefined | any
|
api?: undefined | any;
|
||||||
}
|
};
|
||||||
// see?: {
|
// see?: {
|
||||||
// // 显示查看按钮的权限
|
// // 显示查看按钮的权限
|
||||||
// auth?: string[]
|
// auth?: string[]
|
||||||
// // 显示查看按钮的角色
|
// // 显示查看按钮的角色
|
||||||
// role?: string[]
|
// role?: string[]
|
||||||
// // 按钮文案
|
// // 按钮文案
|
||||||
// text?: string
|
// text?: string
|
||||||
// // 是否显示
|
// // 是否显示
|
||||||
// show?: boolean
|
// show?: boolean
|
||||||
// }
|
// }
|
||||||
import?: {
|
import?: {
|
||||||
// 导入url
|
// 导入url
|
||||||
url?: undefined | any
|
url?: undefined | any;
|
||||||
// 下载模板地址
|
// 下载模板地址
|
||||||
templateUrl?: undefined | any
|
templateUrl?: undefined | any;
|
||||||
// 显示导入按钮的权限
|
// 显示导入按钮的权限
|
||||||
auth?: string[]
|
auth?: string[];
|
||||||
// 显示导入按钮的角色
|
// 显示导入按钮的角色
|
||||||
role?: string[]
|
role?: string[];
|
||||||
// 按钮文案
|
// 按钮文案
|
||||||
text?: string
|
text?: string;
|
||||||
// 是否显示
|
// 是否显示
|
||||||
show?: boolean
|
show?: boolean;
|
||||||
}
|
};
|
||||||
export?: {
|
export?: {
|
||||||
// 导出url
|
// 导出url
|
||||||
url?: undefined | any
|
url?: undefined | any;
|
||||||
// 显示导出按钮的权限
|
// 显示导出按钮的权限
|
||||||
auth?: string[]
|
auth?: string[];
|
||||||
// 显示导出按钮的角色
|
// 显示导出按钮的角色
|
||||||
role?: string[]
|
role?: string[];
|
||||||
// 按钮文案
|
// 按钮文案
|
||||||
text?: string
|
text?: string;
|
||||||
// 是否显示
|
// 是否显示
|
||||||
show?: boolean
|
show?: boolean;
|
||||||
}
|
};
|
||||||
// 是否显示索引列
|
// 是否显示索引列
|
||||||
showIndex?: boolean
|
showIndex?: boolean;
|
||||||
// 索引列名称
|
// 索引列名称
|
||||||
indexLabel?: string
|
indexLabel?: string;
|
||||||
// 设置请求数据label
|
// 设置请求数据label
|
||||||
requestParamsLabel?: undefined
|
requestParamsLabel?: undefined;
|
||||||
// 表格滚动默认宽高
|
// 表格滚动默认宽高
|
||||||
scroll?: {
|
scroll?: {
|
||||||
x?: string
|
x?: string;
|
||||||
y?: string
|
y?: string;
|
||||||
}
|
};
|
||||||
// 调整列宽
|
// 调整列宽
|
||||||
resizable?: boolean
|
resizable?: boolean;
|
||||||
// 是否显示操作列
|
// 是否显示操作列
|
||||||
operationColumn?: boolean
|
operationColumn?: boolean;
|
||||||
// 操作列宽度
|
// 操作列宽度
|
||||||
operationWidth?: number
|
operationWidth?: number;
|
||||||
// 操作列名称
|
// 操作列名称
|
||||||
operationColumnText?: string
|
operationColumnText?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-modal
|
<a-modal
|
||||||
|
:width="prop.width"
|
||||||
|
:fullscreen="isFull"
|
||||||
v-model:visible="modal.visible"
|
v-model:visible="modal.visible"
|
||||||
:on-before-ok="modal.submit"
|
:on-before-ok="modal.submit"
|
||||||
unmount-on-close
|
unmount-on-close
|
||||||
@cancel="modal.cancel"
|
@cancel="modal.cancel"
|
||||||
:width="width"
|
|
||||||
draggable
|
|
||||||
:on-before-cancel="modal.customCancel"
|
|
||||||
v-bind="$attrs"
|
|
||||||
>
|
>
|
||||||
<template #title>
|
<template #title>
|
||||||
{{ prop.title }}
|
{{ prop.title }}
|
||||||
</template>
|
</template>
|
||||||
<slot name="body"></slot>
|
<slot name="body"></slot>
|
||||||
<ma-form ref="maFormRef" :columns="prop.column" v-model="form" :options="{ ...options, showButtons: false }">
|
<a-space v-if="prop.infoColumns.length">
|
||||||
<template #[`inputPrepend-version`]>V </template>
|
<ma-info :columns="prop.infoColumns" :data="prop.infoData" />
|
||||||
|
</a-space>
|
||||||
|
<ma-form ref="maFormRef" :columns="formColumns" v-model="form" :options="{ ...options, showButtons: false }">
|
||||||
|
<template v-for="(value, key) in $slots" #[key]="slotProps" :key="key">
|
||||||
|
<slot :name="key" v-bind="slotProps"></slot>
|
||||||
|
</template>
|
||||||
</ma-form>
|
</ma-form>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
@@ -28,29 +31,50 @@
|
|||||||
import { reactive, ref, watch } from "vue"
|
import { reactive, ref, watch } from "vue"
|
||||||
import MaForm from "@/components/ma-form/index.vue"
|
import MaForm from "@/components/ma-form/index.vue"
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
|
import MaInfo from "@/components/ma-info/index.vue"
|
||||||
|
import { setModalSizeEvent } from "@/utils/common"
|
||||||
|
|
||||||
const emit = defineEmits(["visible", "validateError", "open", "cancel", "close"])
|
const emit = defineEmits(["visible", "validateError", "open", "cancel", "close"])
|
||||||
const form = ref({})
|
const form = ref({})
|
||||||
|
const formColumns = ref([])
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
|
width: { type: Number, default: 1200 }, // modal框大小
|
||||||
|
isFull: { type: Boolean, default: false }, // 是否全屏
|
||||||
title: { type: String, default: "" }, // 弹出框标题
|
title: { type: String, default: "" }, // 弹出框标题
|
||||||
column: { type: Array, default: [] }, // ma-form字段
|
column: { type: Array, default: [] }, // ma-form字段
|
||||||
|
columns: { type: Array, default: [] }, // ma-form字段 别名
|
||||||
|
infoColumns: { type: Array, default: [] },
|
||||||
|
infoData: { type: Object, default: {} },
|
||||||
default_visible: { type: Boolean, default: false }, // 默认隐藏
|
default_visible: { type: Boolean, default: false }, // 默认隐藏
|
||||||
options: { type: Object, default: {} }, // ma-form 属性
|
options: { type: Object, default: {} }, // ma-form 属性
|
||||||
submit: { type: Function, default: () => {} },
|
submit: { type: Function, default: () => {} }
|
||||||
width: { type: String, default: "1000" + "px" },
|
|
||||||
// 自定义异步取消参数
|
|
||||||
customCancel: { type: Function, default: null }
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const isFull = ref(prop.isFull)
|
||||||
|
setModalSizeEvent((config) => {
|
||||||
|
isFull.value = config.isFull
|
||||||
|
})
|
||||||
|
|
||||||
|
formColumns.value = [...prop.column, ...prop.columns]
|
||||||
|
let submitEvent = prop.submit
|
||||||
|
|
||||||
const maFormRef = ref()
|
const maFormRef = ref()
|
||||||
|
|
||||||
const modal = reactive({
|
const modal = reactive({
|
||||||
visible: prop.default_visible,
|
visible: prop.default_visible,
|
||||||
open(data) {
|
open(formData, infoData = {}) {
|
||||||
modal.visible = true
|
modal.visible = true
|
||||||
for (let [key, value] of Object.entries(data)) {
|
for (let [key, value] of Object.entries(formData)) {
|
||||||
form.value[key] = value
|
form.value[key] = value
|
||||||
}
|
}
|
||||||
emit("open", data)
|
for (let [key, value] of Object.entries(infoData)) {
|
||||||
|
prop.infoData[key] = value
|
||||||
|
}
|
||||||
|
emit("open", formData, infoData)
|
||||||
|
},
|
||||||
|
onSubmit(func) {
|
||||||
|
submitEvent = func
|
||||||
|
return this
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
modal.visible = false
|
modal.visible = false
|
||||||
@@ -61,13 +85,7 @@ const modal = reactive({
|
|||||||
emit("validateError", validate)
|
emit("validateError", validate)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return prop.submit(form._rawValue)
|
return submitEvent(form._rawValue)
|
||||||
},
|
|
||||||
customCancel() {
|
|
||||||
if (prop.customCancel) {
|
|
||||||
return prop.customCancel()
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
},
|
||||||
cancel() {
|
cancel() {
|
||||||
emit("cancel")
|
emit("cancel")
|
||||||
@@ -82,11 +100,17 @@ watch(
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const getAttr = (key) => {
|
||||||
|
return form.value[key]
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
open: modal.open,
|
open: modal.open,
|
||||||
close: modal.close,
|
close: modal.close,
|
||||||
form: form,
|
form: form,
|
||||||
formRef: maFormRef
|
getAttr,
|
||||||
|
formRef: maFormRef,
|
||||||
|
onSubmit: modal.onSubmit
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-card
|
<a-card
|
||||||
v-show="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
v-if="
|
||||||
|
(typeof props.component?.display == 'undefined' || props.component?.display === true) &&
|
||||||
|
(hasDisplayTrue(props.component?.formList ?? []) || props.component?.forceShow)
|
||||||
|
"
|
||||||
:class="[props.component?.customClass]"
|
:class="[props.component?.customClass]"
|
||||||
:extra="props.component?.extra"
|
:extra="props.component?.extra"
|
||||||
:bordered="props.component?.bordered"
|
:bordered="props.component?.bordered"
|
||||||
@@ -42,13 +40,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted } from "vue"
|
import { onMounted, inject } from "vue"
|
||||||
import { getComponentName } from "../js/utils.js"
|
import { getComponentName } from "../js/utils.js"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({ component: Object })
|
const props = defineProps({ component: Object })
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
const formModel = inject("formModel")
|
||||||
onMounted(() => {
|
const getColumnService = inject("getColumnService")
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
const columns = inject("columns")
|
||||||
})
|
|
||||||
|
const hasDisplayTrue = (list) => {
|
||||||
|
return list.some((item) => item.display ?? true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
|
rv("onCreated")
|
||||||
|
onMounted(() => rv("onMounted"))
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
@@ -55,7 +59,6 @@
|
|||||||
</template>
|
</template>
|
||||||
<template v-for="(component, componentIndex) in viewFormList[itemIndex]" :key="componentIndex">
|
<template v-for="(component, componentIndex) in viewFormList[itemIndex]" :key="componentIndex">
|
||||||
<component
|
<component
|
||||||
style="line-height:32px;"
|
|
||||||
v-if="!containerItems.includes(component.formType)"
|
v-if="!containerItems.includes(component.formType)"
|
||||||
:is="getComponentName(component?.formType ?? 'input')"
|
:is="getComponentName(component?.formType ?? 'input')"
|
||||||
:component="component"
|
:component="component"
|
||||||
@@ -69,69 +72,88 @@
|
|||||||
</a-collapse-item>
|
</a-collapse-item>
|
||||||
</a-collapse>
|
</a-collapse>
|
||||||
|
|
||||||
<a-table v-else class="w-full" :data="formModel[props.component.dataIndex]" :pagination="false" bordered stripe>
|
<div v-else class="arco-table arco-table-size-large arco-table-border arco-table-stripe arco-table-hover">
|
||||||
<template #columns id="children-columns">
|
<div class="arco-table-container">
|
||||||
<!-- 新增、删除列 -->
|
<table class="arco-table-element" cellpadding="0" cellspacing="0">
|
||||||
<a-table-column :width="60" fixed="left">
|
<thead>
|
||||||
<template #title>
|
<tr class="arco-table-tr">
|
||||||
<a-button type="primary" @click="addItem()" size="small" shape="round">
|
<th class="arco-table-th" width="60">
|
||||||
<template #icon>
|
<span class="arco-table-cell arco-table-cell-align-center">
|
||||||
<icon-plus />
|
<a-button type="primary" @click="addItem()" size="small" shape="round">
|
||||||
|
<template #icon>
|
||||||
|
<icon-plus />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<th class="arco-table-th" :width="60">
|
||||||
|
<span class="arco-table-cell arco-table-cell-align-center">
|
||||||
|
<span class="arco-table-th-title">序号</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
|
<template v-for="component in viewFormList[0]">
|
||||||
|
<th class="arco-table-th" :width="component.width">
|
||||||
|
<span class="arco-table-cell arco-table-cell-align-center">
|
||||||
|
<span class="arco-table-th-title">{{ component.title }}</span>
|
||||||
|
</span>
|
||||||
|
</th>
|
||||||
</template>
|
</template>
|
||||||
</a-button>
|
</tr>
|
||||||
</template>
|
</thead>
|
||||||
<template #cell="{ rowIndex }">
|
<tbody>
|
||||||
<a-button
|
<template v-for="(item, index) in formModel[props.component.dataIndex]">
|
||||||
type="primary"
|
<tr class="arco-table-tr">
|
||||||
status="danger"
|
<td class="arco-table-td">
|
||||||
size="small"
|
<span class="arco-table-cell">
|
||||||
shape="round"
|
<a-button
|
||||||
:disabled="formModel[props.component.dataIndex].length === 1"
|
type="primary"
|
||||||
@click="deleteItem(rowIndex)"
|
status="danger"
|
||||||
>
|
size="small"
|
||||||
<template #icon><icon-minus /></template>
|
shape="round"
|
||||||
</a-button>
|
:disabled="formModel[props.component.dataIndex].length === 1"
|
||||||
</template>
|
@click="deleteItem(index)"
|
||||||
</a-table-column>
|
>
|
||||||
|
<template #icon><icon-minus /></template>
|
||||||
<a-table-column :width="60" fixed="left">
|
</a-button>
|
||||||
<template #title>序号</template>
|
</span>
|
||||||
<template #cell="{ rowIndex }"> {{ rowIndex + 1 }} </template>
|
</td>
|
||||||
</a-table-column>
|
<td class="arco-table-td">
|
||||||
|
<span class="arco-table-cell">
|
||||||
<template v-for="(component, itemIndex) in viewFormList[0]" :key="itemIndex">
|
<span class="arco-table-td-content">{{ index + 1 }}</span>
|
||||||
<a-table-column
|
</span>
|
||||||
:width="component.width"
|
</td>
|
||||||
:title="component.title ?? '未命名'"
|
<template v-for="component in viewFormList[index]">
|
||||||
:align="component.align || 'left'"
|
<td class="arco-table-td">
|
||||||
:fixed="component.fixed"
|
{{ (component.hideLabel = true ? "" : "") }}
|
||||||
>
|
<span class="arco-table-cell">
|
||||||
<template #cell="{ rowIndex }">
|
<component
|
||||||
<component
|
v-if="!containerItems.includes(component.formType)"
|
||||||
v-if="!containerItems.includes(component.formType)"
|
:is="getComponentName(component.formType ?? 'input')"
|
||||||
:is="getComponentName(component.formType ?? 'input')"
|
:component="component"
|
||||||
:component="component"
|
:customField="getChildrenDataIndex(index, component.dataIndex)"
|
||||||
:customField="getChildrenDataIndex(rowIndex, component.dataIndex)"
|
>
|
||||||
>
|
<template v-for="slot in Object.keys($slots)" #[slot]="component">
|
||||||
<template v-for="slot in Object.keys($slots)" #[slot]="component">
|
<slot :name="slot" v-bind="component" />
|
||||||
<slot :name="slot" v-bind="component" />
|
</template>
|
||||||
|
</component>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
</template>
|
</template>
|
||||||
</component>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
</a-table-column>
|
</tbody>
|
||||||
</template>
|
</table>
|
||||||
</template>
|
</div>
|
||||||
</a-table>
|
</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, provide, onMounted, watch, nextTick, shallowRef, isRef } from "vue"
|
import { ref, inject, onMounted, watch, nextTick } from "vue"
|
||||||
import { cloneDeep, get, isArray, isUndefined, set } from "lodash"
|
import { cloneDeep, isArray, isUndefined } from "lodash-es"
|
||||||
import { getComponentName, containerItems } from "../js/utils.js"
|
import { getComponentName, containerItems } from "../js/utils.js"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
import { loadDict, handlerCascader } from "../js/networkRequest.js"
|
import { loadDict } from "../js/networkRequest.js"
|
||||||
import arrayComponentDefault from "../js/defaultArrayComponent.js"
|
|
||||||
|
|
||||||
const props = defineProps({ component: Object })
|
const props = defineProps({ component: Object })
|
||||||
const formList = props.component.formList
|
const formList = props.component.formList
|
||||||
@@ -139,6 +161,11 @@ const viewFormList = ref([])
|
|||||||
const options = inject("options")
|
const options = inject("options")
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
const dictList = inject("dictList")
|
const dictList = inject("dictList")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
const defaultOpenKeys = [0]
|
const defaultOpenKeys = [0]
|
||||||
|
|
||||||
if (!formModel.value[props.component.dataIndex]) {
|
if (!formModel.value[props.component.dataIndex]) {
|
||||||
@@ -160,7 +187,7 @@ watch(
|
|||||||
value[index] = Object.fromEntries(data)
|
value[index] = Object.fromEntries(data)
|
||||||
}
|
}
|
||||||
viewFormList.value[index] = cloneDeep(formList)
|
viewFormList.value[index] = cloneDeep(formList)
|
||||||
maEvent.customeEvent(props.component, { formList: viewFormList.value[index], data, index }, "onAdd")
|
rv("onAdd", { formList: viewFormList.value[index], data, index })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -173,23 +200,21 @@ if (props.component.type == "table") {
|
|||||||
formList.map((item) => {
|
formList.map((item) => {
|
||||||
item["hideLabel"] = true
|
item["hideLabel"] = true
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
formModel.value[props.component.dataIndex].map((item, index) => {
|
||||||
|
if (index > 0) defaultOpenKeys.push(index)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// 默认不展开所有的collapse
|
|
||||||
// else {
|
|
||||||
// formModel.value[props.component.dataIndex].map((item, index) => {
|
|
||||||
// if (index > 0) defaultOpenKeys.push(index)
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
const addItem = async (data = {}) => {
|
const addItem = async (data = {}) => {
|
||||||
let index = formModel.value[props.component.dataIndex].length
|
let index = formModel.value[props.component.dataIndex].length
|
||||||
viewFormList.value[index] = cloneDeep(formList)
|
viewFormList.value[index] = cloneDeep(formList)
|
||||||
maEvent.customeEvent(props.component, { formList: viewFormList.value[index], data, index: index }, "onAdd")
|
rv("onAdd", { formList: viewFormList.value[index], data, index })
|
||||||
formModel.value[props.component.dataIndex].push(data)
|
formModel.value[props.component.dataIndex].push(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteItem = async (index) => {
|
const deleteItem = async (index) => {
|
||||||
let res = await maEvent.customeEvent(props.component, { index }, "onDelete")
|
let res = await rv("onDelete", { index })
|
||||||
if (isUndefined(res) || res === true) {
|
if (isUndefined(res) || res === true) {
|
||||||
viewFormList.value.splice(index, 1)
|
viewFormList.value.splice(index, 1)
|
||||||
await nextTick()
|
await nextTick()
|
||||||
@@ -201,14 +226,14 @@ const getChildrenDataIndex = (index, dataIndex) => {
|
|||||||
return [props.component.dataIndex, index, dataIndex].join(".")
|
return [props.component.dataIndex, index, dataIndex].join(".")
|
||||||
}
|
}
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
if (formModel.value[props.component.dataIndex].length === 0) {
|
if (formModel.value[props.component.dataIndex].length === 0) {
|
||||||
for (let i = 0; i < (props.component.emptyRow ?? 1); i++) {
|
for (let i = 0; i < (props.component.emptyRow ?? 1); i++) {
|
||||||
await addItem()
|
await addItem()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
rv("onMounted")
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-col
|
<a-col
|
||||||
v-show="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
v-if="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
||||||
:class="[props.component?.customClass]"
|
:class="[props.component?.customClass]"
|
||||||
:span="props.component?.span ?? 12"
|
:span="props.component?.span ?? 12"
|
||||||
:offset="props.component?.offset"
|
:offset="props.component?.offset"
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-show="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
v-if="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
||||||
:class="['grid-responsive-padding', props.component?.customClass]"
|
:class="['grid-responsive-padding', props.component?.customClass]"
|
||||||
:style="props.component?.style"
|
:style="props.component?.style"
|
||||||
:span="props.component?.span ?? 12"
|
:span="props.component?.span ?? 12"
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-show="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
v-if="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
||||||
:class="[gridClass, props.component?.customClass]"
|
:class="[gridClass, props.component?.customClass]"
|
||||||
:style="props.component?.style"
|
:style="props.component?.style"
|
||||||
>
|
>
|
||||||
@@ -24,16 +19,20 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from "vue"
|
import { ref, onMounted, inject } from "vue"
|
||||||
import MaGridTailwindCol from "./grid-tailwind-col.vue"
|
import MaGridTailwindCol from "./grid-tailwind-col.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({ component: Object })
|
const props = defineProps({ component: Object })
|
||||||
const gridClass = ref(["ma-grid", "grid", "lg:grid-cols-" + props.component?.colNumber ?? 1])
|
const gridClass = ref(["ma-grid", "grid", "lg:grid-cols-" + props.component?.colNumber ?? 1])
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
const formModel = inject("formModel")
|
||||||
onMounted(() => {
|
const getColumnService = inject("getColumnService")
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
const columns = inject("columns")
|
||||||
})
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
|
rv("onCreated")
|
||||||
|
onMounted(() => rv("onMounted"))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-row
|
<a-row
|
||||||
v-show="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
v-if="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
||||||
:class="[props.component?.customClass]"
|
:class="[props.component?.customClass]"
|
||||||
:gutter="props.component?.gutter"
|
:gutter="props.component?.gutter"
|
||||||
:justify="props.component?.justify"
|
:justify="props.component?.justify"
|
||||||
@@ -28,13 +23,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted } from "vue"
|
import { onMounted, inject } from "vue"
|
||||||
import MaGridCol from "./grid-col.vue"
|
import MaGridCol from "./grid-col.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({ component: Object })
|
const props = defineProps({ component: Object })
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
const formModel = inject("formModel")
|
||||||
onMounted(() => {
|
const getColumnService = inject("getColumnService")
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
const columns = inject("columns")
|
||||||
})
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
|
rv("onCreated")
|
||||||
|
onMounted(() => rv("onMounted"))
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<td
|
<td
|
||||||
v-show="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
v-if="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
||||||
:class="['table-cell', props.component?.customClass]"
|
:class="['table-cell', props.component?.customClass]"
|
||||||
:style="props.component?.style"
|
:style="props.component?.style"
|
||||||
:colspan="props.component.colSpan"
|
:colspan="props.component.colSpan"
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<table
|
<table
|
||||||
v-show="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
v-if="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
||||||
:class="['table-container', props.component?.customClass]"
|
:class="['table-container', props.component?.customClass]"
|
||||||
:style="props.component?.style"
|
:style="props.component?.style"
|
||||||
>
|
>
|
||||||
@@ -33,15 +28,19 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted } from "vue"
|
import { onMounted, inject } from "vue"
|
||||||
import MaTableCell from "./table-cell.vue"
|
import MaTableCell from "./table-cell.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({ component: Object })
|
const props = defineProps({ component: Object })
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
const formModel = inject("formModel")
|
||||||
onMounted(() => {
|
const getColumnService = inject("getColumnService")
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
const columns = inject("columns")
|
||||||
})
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
|
rv("onCreated")
|
||||||
|
onMounted(() => rv("onMounted"))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-tabs
|
<a-tabs
|
||||||
v-show="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
v-if="typeof props.component?.display == 'undefined' || props.component?.display === true"
|
||||||
:class="[props.component?.customClass]"
|
:class="[props.component?.customClass]"
|
||||||
:trigger="props.component?.trigger"
|
:trigger="props.component?.trigger"
|
||||||
:position="props.component?.position"
|
:position="props.component?.position"
|
||||||
@@ -23,10 +18,10 @@
|
|||||||
:hide-content="props.component?.hideContent"
|
:hide-content="props.component?.hideContent"
|
||||||
:lazy-load="props.component?.lazyLoad"
|
:lazy-load="props.component?.lazyLoad"
|
||||||
:destroy-on-hide="props.component?.destroyOnHide"
|
:destroy-on-hide="props.component?.destroyOnHide"
|
||||||
@change="maEvent.handleChangeEvent(props.component, $event)"
|
@change="rv('onChange', $event)"
|
||||||
@tab-click="maEvent.handleTabClickEvent(props.component, $event)"
|
@tab-click="rv('onTabClick', $event)"
|
||||||
@add="maEvent.handleTabAddEvent(props.component)"
|
@add="tabAddEvent(props.component, { formModel, getColumnService, columns })"
|
||||||
@delete="maEvent.handleTabDeleteEvent(props.component, $event)"
|
@delete="tabDeleteEvent(props.component, $event, { formModel, getColumnService, columns })"
|
||||||
>
|
>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<slot :name="`tabExtra-${props.component?.dataIndex ?? ''}`"></slot>
|
<slot :name="`tabExtra-${props.component?.dataIndex ?? ''}`"></slot>
|
||||||
@@ -54,13 +49,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted } from "vue"
|
import { onMounted, inject } from "vue"
|
||||||
import { getComponentName } from "../js/utils.js"
|
import { getComponentName } from "../js/utils.js"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent, tabAddEvent, tabDeleteEvent } from "../js/event.js"
|
||||||
const props = defineProps({ component: Object })
|
const props = defineProps({ component: Object })
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
const formModel = inject("formModel")
|
||||||
onMounted(() => {
|
const getColumnService = inject("getColumnService")
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
const columns = inject("columns")
|
||||||
})
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
|
rv("onCreated")
|
||||||
|
onMounted(() => rv("onMounted"))
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -24,10 +19,12 @@
|
|||||||
:strict="props.component.strict"
|
:strict="props.component.strict"
|
||||||
:filter-option="props.component.filterOption"
|
:filter-option="props.component.filterOption"
|
||||||
:allow-clear="props.component.allowClear ?? true"
|
:allow-clear="props.component.allowClear ?? true"
|
||||||
@change="maEvent.customeEvent(props.component, $event, 'onChange')"
|
@change="rv('onChange', $event)"
|
||||||
@search="maEvent.customeEvent(props.component, $event, 'onSearch')"
|
@search="rv('onSearch', $event)"
|
||||||
@select="maEvent.customeEvent(props.component, $event, 'onSelect')"
|
@select="rv('onSelect', $event)"
|
||||||
@clear="maEvent.customeEvent(props.component, $event, 'onClear')"
|
@clear="rv('onClear')"
|
||||||
|
@dropdown-scroll="rv('onDropdownScroll')"
|
||||||
|
@dropdown-reach-bottom="rv('onDropdownReachBottom')"
|
||||||
>
|
>
|
||||||
<slot :name="`autoCompleteFooter-${props.component.dataIndex}`"></slot>
|
<slot :name="`autoCompleteFooter-${props.component.dataIndex}`"></slot>
|
||||||
</a-auto-complete>
|
</a-auto-complete>
|
||||||
@@ -37,15 +34,19 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index, ""))
|
const value = ref(get(formModel.value, index, ""))
|
||||||
|
|
||||||
@@ -61,8 +62,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,43 +1,44 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
<div>
|
||||||
<a-button
|
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
||||||
:type="props.component.type"
|
<a-button
|
||||||
:status="props.component.status"
|
:type="props.component.type"
|
||||||
:size="props.component.size"
|
:status="props.component.status"
|
||||||
:shape="props.component.shape"
|
:size="props.component.size"
|
||||||
:disabled="props.component.disabled"
|
:shape="props.component.shape"
|
||||||
:long="props.component.long"
|
:disabled="props.component.disabled"
|
||||||
:loading="props.component.loading"
|
:long="props.component.long"
|
||||||
:html-type="props.component.htmlType"
|
:loading="props.component.loading"
|
||||||
:href="props.component.href"
|
:html-type="props.component.htmlType"
|
||||||
@click="maEvent.handleCommonEvent(props.component, 'onClick')"
|
:href="props.component.href"
|
||||||
>
|
@click="rv('onClick')"
|
||||||
<template #icon v-if="props.component.icon">
|
>
|
||||||
<component :is="props.component.icon" />
|
<template #icon v-if="props.component.icon">
|
||||||
</template>
|
<component :is="props.component.icon" />
|
||||||
{{ props.component.title ?? "button" }}
|
</template>
|
||||||
</a-button>
|
{{ props.component.title ?? "button" }}
|
||||||
</slot>
|
</a-button>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted } from "vue"
|
import { onMounted, inject } from "vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object
|
component: Object
|
||||||
})
|
})
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
const formModel = inject("formModel")
|
||||||
onMounted(() => {
|
const getColumnService = inject("getColumnService")
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
const columns = inject("columns")
|
||||||
})
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
|
rv("onCreated")
|
||||||
|
onMounted(() => rv("onMounted"))
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -45,13 +40,13 @@
|
|||||||
:value-key="props.component.valueKey"
|
:value-key="props.component.valueKey"
|
||||||
:fallback="props.component.fallback"
|
:fallback="props.component.fallback"
|
||||||
:expand-child="props.component.expandChild"
|
:expand-child="props.component.expandChild"
|
||||||
@change="maEvent.handleChangeEvent(props.component, $event)"
|
@change="rv('onChange', $event)"
|
||||||
@input-value-change="maEvent.handleInputEvent(props.component, $event)"
|
@search="rv('onSearch', $event)"
|
||||||
@popup-visible-change="maEvent.customeEvent(props.component, $event, 'onPopupVisibleChange')"
|
@input-value-change="rv('onInputValueChange', $event)"
|
||||||
@clear="maEvent.handleCommonEvent(props.component, 'onClear')"
|
@popup-visible-change="rv('onPopupVisibleChange', $event)"
|
||||||
@focus="maEvent.handleCommonEvent(props.component, 'onFocus')"
|
@clear="rv('onClear')"
|
||||||
@blur="maEvent.handleCommonEvent(props.component, 'onBlur')"
|
@focus="rv('onFocus')"
|
||||||
@search="maEvent.customeEvent(props.component, $event, 'onSearch')"
|
@blur="rv('onBlur')"
|
||||||
>
|
>
|
||||||
</a-cascader>
|
</a-cascader>
|
||||||
</slot>
|
</slot>
|
||||||
@@ -60,9 +55,9 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
@@ -71,6 +66,10 @@ const props = defineProps({
|
|||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
const dictList = inject("dictList")
|
const dictList = inject("dictList")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const dictIndex = index.match(/^(\w+\.)\d+\./)
|
const dictIndex = index.match(/^(\w+\.)\d+\./)
|
||||||
? index.match(/^(\w+\.)\d+\./)[1] + props.component.dataIndex
|
? index.match(/^(\w+\.)\d+\./)[1] + props.component.dataIndex
|
||||||
@@ -99,8 +98,6 @@ if (
|
|||||||
value.value = value.value + ""
|
value.value = value.value + ""
|
||||||
}
|
}
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -20,7 +15,7 @@
|
|||||||
:max="props.component.max"
|
:max="props.component.max"
|
||||||
:direction="props.component.direction"
|
:direction="props.component.direction"
|
||||||
:disabled="props.component.disabled"
|
:disabled="props.component.disabled"
|
||||||
@change="maEvent.handleChangeEvent(props.component, $event)"
|
@change="rv('onChange', $event)"
|
||||||
>
|
>
|
||||||
<template v-for="(item, index) in dictList[dictIndex] ?? []">
|
<template v-for="(item, index) in dictList[dictIndex] ?? []">
|
||||||
<a-checkbox :value="item.value" :disabled="item.disabled" :indeterminate="item.indeterminate">{{
|
<a-checkbox :value="item.value" :disabled="item.disabled" :indeterminate="item.indeterminate">{{
|
||||||
@@ -34,9 +29,9 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
@@ -45,6 +40,10 @@ const props = defineProps({
|
|||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
const dictList = inject("dictList")
|
const dictList = inject("dictList")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const dictIndex = index.match(/^(\w+\.)\d+\./)
|
const dictIndex = index.match(/^(\w+\.)\d+\./)
|
||||||
? index.match(/^(\w+\.)\d+\./)[1] + props.component.dataIndex
|
? index.match(/^(\w+\.)\d+\./)[1] + props.component.dataIndex
|
||||||
@@ -63,8 +62,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -22,10 +17,10 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaCityLinkage from "@/components/ma-cityLinkage/index.vue"
|
import MaCityLinkage from "@/components/ma-cityLinkage/index.vue"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
@@ -33,6 +28,10 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -48,8 +47,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -21,10 +16,10 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaColorPicker from "@/components/ma-colorPicker/index.vue"
|
import MaColorPicker from "@/components/ma-colorPicker/index.vue"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
@@ -32,6 +27,9 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const dictList = inject("dictList")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) => await runEvent(props.component, ev, value, { formModel, dictList, columns })
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -47,8 +45,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -20,16 +15,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, getCurrentInstance, watch } from "vue"
|
import { onMounted, getCurrentInstance, watch, inject } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
const app = getCurrentInstance().appContext.app
|
const app = getCurrentInstance().appContext.app
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -40,8 +41,8 @@ if (
|
|||||||
app.component(props.component.dataIndex, props.component.component)
|
app.component(props.component.dataIndex, props.component.component)
|
||||||
}
|
}
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
runEvent("onCreated", "handleCommonEvent")
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
runEvent("onMounted", "handleCommonEvent")
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
85
cdTMP/src/components/ma-form/formItem/form-dialog.vue
Normal file
85
cdTMP/src/components/ma-form/formItem/form-dialog.vue
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<maDialog v-model:visible="visible" :footer="false" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, inject, ref, h, computed } from "vue"
|
||||||
|
import { runEvent } from "../js/event.js"
|
||||||
|
import { Modal, Drawer } from "@arco-design/web-vue"
|
||||||
|
import MaForm from "@/components/ma-form/index.vue"
|
||||||
|
import { isFunction } from "lodash-es"
|
||||||
|
const props = defineProps({
|
||||||
|
component: Object
|
||||||
|
})
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
const openDialog = () => (visible.value = true)
|
||||||
|
const getDataIndex = () => props.component?.dataIndex
|
||||||
|
|
||||||
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
|
const form = computed({
|
||||||
|
get() {
|
||||||
|
return formModel.value[getDataIndex()]
|
||||||
|
},
|
||||||
|
set(newVal) {
|
||||||
|
formModel.value[getDataIndex()] = newVal
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const maDialog = (p, ctx) => {
|
||||||
|
const componentProps = { formList: {}, options: {} }
|
||||||
|
const evs = {}
|
||||||
|
Object.keys(props.component).map((key) => {
|
||||||
|
if (!/^on[A-Za-z]+/g.test(key)) {
|
||||||
|
componentProps[key] = props.component[key]
|
||||||
|
} else {
|
||||||
|
if (isFunction(props.component[key])) {
|
||||||
|
evs[key] = function () {
|
||||||
|
const argsList = Array.prototype.slice.call(arguments)
|
||||||
|
props.component[key](...argsList, { formModel, getColumnService, columns })
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
evs[key] = function () {
|
||||||
|
const argsList = Array.prototype.slice.call(arguments)
|
||||||
|
rv(key, { ...argsList })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return h(
|
||||||
|
componentProps?.type === "drawer" ? Drawer : Modal,
|
||||||
|
{
|
||||||
|
...Object.assign(componentProps, p),
|
||||||
|
...evs
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: () =>
|
||||||
|
h(
|
||||||
|
MaForm,
|
||||||
|
{
|
||||||
|
columns: componentProps.formList,
|
||||||
|
options: Object.assign(componentProps.options),
|
||||||
|
modelValue: form.value,
|
||||||
|
onSubmit: async (data, done) => await rv("onSubmit", { data, done })
|
||||||
|
},
|
||||||
|
componentProps?.formSlot
|
||||||
|
),
|
||||||
|
...componentProps?.dialogSlot
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
rv("onCreated")
|
||||||
|
onMounted(() => rv("onMounted"))
|
||||||
|
|
||||||
|
defineExpose({ openDialog, getDataIndex })
|
||||||
|
</script>
|
||||||
@@ -1,37 +1,38 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
<div>
|
||||||
<a-divider
|
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
||||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
<a-divider
|
||||||
:class="[props.component.customClass]"
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
:margin="props.component.margin"
|
:class="[props.component.customClass]"
|
||||||
:direction="props.component.direction"
|
:margin="props.component.margin"
|
||||||
:orientation="props.component.orientation"
|
:direction="props.component.direction"
|
||||||
:type="props.component.type"
|
:orientation="props.component.orientation"
|
||||||
:size="props.component.size"
|
:type="props.component.type"
|
||||||
>
|
:size="props.component.size"
|
||||||
{{ props.component?.title ?? "" }}
|
>
|
||||||
</a-divider>
|
{{ props.component?.title ?? "" }}
|
||||||
</slot>
|
</a-divider>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted } from "vue"
|
import { onMounted, inject } from "vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object
|
component: Object
|
||||||
})
|
})
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
const formModel = inject("formModel")
|
||||||
onMounted(() => {
|
const getColumnService = inject("getColumnService")
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
const columns = inject("columns")
|
||||||
})
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
|
rv("onCreated")
|
||||||
|
onMounted(() => rv("onMounted"))
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
@@ -10,7 +14,7 @@
|
|||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:height="props.component.height"
|
:height="props.component.height"
|
||||||
:id="props.component.id"
|
:id="props.component.id"
|
||||||
@change="maEvent.handleChangeEvent(props.component, $event)"
|
@change="rv('onChange', $event)"
|
||||||
>
|
>
|
||||||
</ma-editor>
|
</ma-editor>
|
||||||
</slot>
|
</slot>
|
||||||
@@ -19,16 +23,20 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaEditor from "@/components/ma-editor/index.vue"
|
import MaEditor from "@/components/ma-editor/index.vue"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -44,8 +52,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -21,17 +16,20 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaIconPicker from "@/components/ma-icon/index.vue"
|
import MaIconPicker from "@/components/ma-icon/index.vue"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
const dictList = inject("dictList")
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -47,8 +45,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
>
|
>
|
||||||
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
||||||
<a-input-number
|
<a-input-number
|
||||||
v-model="value"
|
v-model.trim="value"
|
||||||
:size="props.component.size"
|
:size="props.component.size"
|
||||||
:allow-clear="props.component.allowClear ?? true"
|
:allow-clear="props.component.allowClear ?? true"
|
||||||
:disabled="props.component.disabled"
|
:disabled="props.component.disabled"
|
||||||
@@ -21,12 +21,18 @@
|
|||||||
:formatter="props.component.formatter"
|
:formatter="props.component.formatter"
|
||||||
:parser="props.component.parser"
|
:parser="props.component.parser"
|
||||||
:model-event="props.component.modelEvent"
|
:model-event="props.component.modelEvent"
|
||||||
@input="maEvent.handleInputEvent(props.component, $event)"
|
@input="rv('onInput', $event)"
|
||||||
@change="maEvent.handleChangeEvent(props.component, $event)"
|
@change="rv('onChange', $event)"
|
||||||
@clear="maEvent.handleCommonEvent(props.component, 'onClear')"
|
@clear="rv('onClear')"
|
||||||
@focus="maEvent.handleCommonEvent(props.component, 'onFocus')"
|
@focus="rv('onFocus')"
|
||||||
@blur="maEvent.handleCommonEvent(props.component, 'onBlur')"
|
@blur="rv('onBlur')"
|
||||||
>
|
>
|
||||||
|
<template #prepend v-if="props.component.openPrepend">
|
||||||
|
<slot :name="`inputPrepend-${props.component.dataIndex}`" />
|
||||||
|
</template>
|
||||||
|
<template #append v-if="props.component.openAppend">
|
||||||
|
<slot :name="`inputAppend-${props.component.dataIndex}`" />
|
||||||
|
</template>
|
||||||
<template #suffix v-if="props.component.openSuffix">
|
<template #suffix v-if="props.component.openSuffix">
|
||||||
<slot :name="`inputSuffix-${props.component.dataIndex}`" />
|
<slot :name="`inputSuffix-${props.component.dataIndex}`" />
|
||||||
</template>
|
</template>
|
||||||
@@ -40,18 +46,25 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set, toNumber, isNaN } from "lodash"
|
import { get, set, toNumber, isNaN } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(toNumber(get(formModel.value, index)))
|
const value = ref(toNumber(get(formModel.value, index)))
|
||||||
|
|
||||||
|
const rv = async (ev, value = undefined) => {
|
||||||
|
if (ev === "onChange") set(formModel.value, index, value)
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => get(formModel.value, index),
|
() => get(formModel.value, index),
|
||||||
(vl) => (value.value = toNumber(vl))
|
(vl) => (value.value = toNumber(vl))
|
||||||
@@ -65,8 +78,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
@@ -19,13 +23,13 @@
|
|||||||
:format-tag="props.component.formatTag"
|
:format-tag="props.component.formatTag"
|
||||||
:unique-value="props.component.uniqueValue"
|
:unique-value="props.component.uniqueValue"
|
||||||
:field-names="props.component.fieldNames"
|
:field-names="props.component.fieldNames"
|
||||||
@input-value-change="maEvent.customeEvent(props.component, $event, 'onInputValueChange')"
|
@input-value-change="rv('onInputValueChange', $event)"
|
||||||
@change="maEvent.handleChangeEvent(props.component, $event)"
|
@change="rv('onChange', $event)"
|
||||||
@remove="maEvent.customeEvent(props.component, $event, 'onRemove')"
|
@remove="rv('onRemove', $event)"
|
||||||
@press-enter="maEvent.customeEvent(props.component, $event, 'onPressEnter')"
|
@press-enter="rv('onPressEnter', $event)"
|
||||||
@clear="maEvent.handleCommonEvent(props.component, 'onClear')"
|
@clear="rv('onClear')"
|
||||||
@focus="maEvent.handleCommonEvent(props.component, 'onFocus')"
|
@focus="rv('onFocus')"
|
||||||
@blur="maEvent.handleCommonEvent(props.component, 'onBlur')"
|
@blur="rv('onBlur')"
|
||||||
>
|
>
|
||||||
<template #suffix v-if="props.component.openSuffix">
|
<template #suffix v-if="props.component.openSuffix">
|
||||||
<slot :name="`inputSuffix-${props.component.dataIndex}`" />
|
<slot :name="`inputSuffix-${props.component.dataIndex}`" />
|
||||||
@@ -40,15 +44,19 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -64,8 +72,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
@@ -5,7 +9,6 @@
|
|||||||
:custom-field="props.customField"
|
:custom-field="props.customField"
|
||||||
>
|
>
|
||||||
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
||||||
<!-- chen.xiugai-warning -->
|
|
||||||
<component
|
<component
|
||||||
:is="getComponentName()"
|
:is="getComponentName()"
|
||||||
v-model.trim="value"
|
v-model.trim="value"
|
||||||
@@ -24,13 +27,13 @@
|
|||||||
:search-button="props.component.searchButton"
|
:search-button="props.component.searchButton"
|
||||||
:loading="props.component.invisibleButton"
|
:loading="props.component.invisibleButton"
|
||||||
:button-text="props.component.buttonText"
|
:button-text="props.component.buttonText"
|
||||||
@input="maEvent.handleInputEvent(props.component, $event)"
|
@input="rv('onInput', $event)"
|
||||||
@change="maEvent.handleChangeEvent(props.component, $event)"
|
@change="rv('onChange', $event)"
|
||||||
@press-enter="maEvent.handleCommonEvent(props.component, 'onPressEnter')"
|
@press-enter="rv('onPressEnter')"
|
||||||
@clear="maEvent.handleCommonEvent(props.component, 'onClear')"
|
@clear="rv('onClear')"
|
||||||
@focus="maEvent.handleCommonEvent(props.component, 'onFocus')"
|
@focus="rv('onFocus')"
|
||||||
@blur="maEvent.handleCommonEvent(props.component, 'onBlur')"
|
@blur="rv('onBlur')"
|
||||||
@search="maEvent.handleInputSearchEvent(props.component, $event)"
|
@search="rv('onSearch', $event)"
|
||||||
>
|
>
|
||||||
<template #prepend v-if="props.component.openPrepend">
|
<template #prepend v-if="props.component.openPrepend">
|
||||||
<slot :name="`inputPrepend-${props.component.dataIndex}`" />
|
<slot :name="`inputPrepend-${props.component.dataIndex}`" />
|
||||||
@@ -51,17 +54,26 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
//后端传入数字类型导致报错 Invalid prop: type check failed for prop "modelValue". Expected String with value "0", got Number with value 0
|
||||||
|
const toVal = ref(`${get(formModel.value, index)}`)
|
||||||
|
const value = ref()
|
||||||
|
if (toVal.value != "undefined") {
|
||||||
|
value.value = toVal.value
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => get(formModel.value, index),
|
() => get(formModel.value, index),
|
||||||
@@ -87,8 +99,6 @@ const getComponentName = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
|
|||||||
109
cdTMP/src/components/ma-form/formItem/form-key-value.vue
Normal file
109
cdTMP/src/components/ma-form/formItem/form-key-value.vue
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<ma-form-item
|
||||||
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
|
:component="props.component"
|
||||||
|
:custom-field="props.customField"
|
||||||
|
>
|
||||||
|
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
||||||
|
<a-table
|
||||||
|
class="w-full"
|
||||||
|
row-key="keys"
|
||||||
|
:pagination="false"
|
||||||
|
@change="handleChange"
|
||||||
|
:data="value"
|
||||||
|
:draggable="{ type: 'handle', width: 40 }"
|
||||||
|
>
|
||||||
|
<template #columns>
|
||||||
|
<a-table-column title="Key" align="center">
|
||||||
|
<template #cell="{ record }">
|
||||||
|
<a-input v-model="record.key" />
|
||||||
|
</template>
|
||||||
|
</a-table-column>
|
||||||
|
<a-table-column title="Value" align="center">
|
||||||
|
<template #cell="{ record }">
|
||||||
|
<a-input v-model="record.value" />
|
||||||
|
</template>
|
||||||
|
</a-table-column>
|
||||||
|
<a-table-column title="操作" align="center">
|
||||||
|
<template #cell="{ rowIndex }">
|
||||||
|
<a-space>
|
||||||
|
<a-button size="small" type="primary" @click="plus(rowIndex)"
|
||||||
|
><template #icon><icon-plus /></template
|
||||||
|
></a-button>
|
||||||
|
<a-button size="small" type="primary" @click="minus(rowIndex)"
|
||||||
|
><template #icon><icon-minus /></template
|
||||||
|
></a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</a-table-column>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</slot>
|
||||||
|
</ma-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
|
import { get, set, cloneDeep, isArray } from "lodash-es"
|
||||||
|
import MaFormItem from "./form-item.vue"
|
||||||
|
import { runEvent } from "../js/event.js"
|
||||||
|
import { Message } from "@arco-design/web-vue"
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
component: Object,
|
||||||
|
customField: { type: String, default: undefined }
|
||||||
|
})
|
||||||
|
|
||||||
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const dictList = inject("dictList")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
const index = props.customField ?? props.component.dataIndex
|
||||||
|
const dictIndex = index.match(/^(\w+\.)\d+\./)
|
||||||
|
? index.match(/^(\w+\.)\d+\./)[1] + props.component.dataIndex
|
||||||
|
: props.component.dataIndex
|
||||||
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => get(formModel.value, index),
|
||||||
|
(vl) => (value.value = vl)
|
||||||
|
)
|
||||||
|
watch(
|
||||||
|
() => value.value,
|
||||||
|
(v) => {
|
||||||
|
set(formModel.value, index, v)
|
||||||
|
index.indexOf(".") > -1 && delete formModel.value[index]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!isArray(value.value) || value.value.length === 0) {
|
||||||
|
value.value = [{ key: "", value: "" }]
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChange = (data) => {
|
||||||
|
value.value = data
|
||||||
|
}
|
||||||
|
|
||||||
|
const plus = (index) => {
|
||||||
|
value.value.splice(index + 1, 0, { key: "", value: "" })
|
||||||
|
}
|
||||||
|
|
||||||
|
const minus = (index) => {
|
||||||
|
if (value.value.length === 1) {
|
||||||
|
Message.info("最少要保留一个")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const data = cloneDeep(value.value)
|
||||||
|
data.splice(index, 1)
|
||||||
|
value.value = cloneDeep(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
rv("onCreated")
|
||||||
|
onMounted(() => rv("onMounted"))
|
||||||
|
</script>
|
||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
||||||
@@ -15,7 +10,7 @@
|
|||||||
:disabled="props.component.disabled"
|
:disabled="props.component.disabled"
|
||||||
:loading="props.component.loading"
|
:loading="props.component.loading"
|
||||||
:href="props.component.href"
|
:href="props.component.href"
|
||||||
@click="maEvent.handleCommonEvent(props.component, 'onClick')"
|
@click="rv('onClick')"
|
||||||
>
|
>
|
||||||
<template #icon v-if="props.component.icon">
|
<template #icon v-if="props.component.icon">
|
||||||
<component :is="props.component.icon" />
|
<component :is="props.component.icon" />
|
||||||
@@ -26,14 +21,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted } from "vue"
|
import { onMounted, inject } from "vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object
|
component: Object
|
||||||
})
|
})
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
const formModel = inject("formModel")
|
||||||
onMounted(() => {
|
const getColumnService = inject("getColumnService")
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
const columns = inject("columns")
|
||||||
})
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
|
rv("onCreated")
|
||||||
|
onMounted(() => rv("onMounted"))
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -26,12 +21,12 @@
|
|||||||
:error="props.component.error"
|
:error="props.component.error"
|
||||||
:placeholder="props.component.placeholder ?? `请输入${props.component.title}`"
|
:placeholder="props.component.placeholder ?? `请输入${props.component.title}`"
|
||||||
:type="props.component.type"
|
:type="props.component.type"
|
||||||
@input="maEvent.handleInputEvent(props.component, $event)"
|
@input="rv('onInput', $event)"
|
||||||
@clear="maEvent.handleCommonEvent(props.component, 'onClear')"
|
@clear="rv('onClear')"
|
||||||
@focus="maEvent.handleCommonEvent(props.component, 'onFocus')"
|
@focus="rv('onFocus')"
|
||||||
@blur="maEvent.handleCommonEvent(props.component, 'onBlur')"
|
@blur="rv('onBlur')"
|
||||||
@search="maEvent.customeEvent(props.component, $event, 'onSearch')"
|
@search="rv('onSearch', $event)"
|
||||||
@select="maEvent.customeEvent(props.component, $event, 'onSelect')"
|
@select="rv('onSelect', $event)"
|
||||||
>
|
>
|
||||||
</a-mention>
|
</a-mention>
|
||||||
</slot>
|
</slot>
|
||||||
@@ -40,15 +35,19 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -64,8 +63,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -19,8 +14,8 @@
|
|||||||
v-model="value"
|
v-model="value"
|
||||||
:placeholder="
|
:placeholder="
|
||||||
props.component.formType === 'range'
|
props.component.formType === 'range'
|
||||||
? ['请选择开始时间', '请选择结束时间']
|
? (props.component.placeholder ?? ['请选择开始时间', '请选择结束时间'])
|
||||||
: `请选择${props.component.title}`
|
: (props.component.placeholder ?? `请选择${props.component.title}`)
|
||||||
"
|
"
|
||||||
:hide-trigger="props.component.hideTrigger"
|
:hide-trigger="props.component.hideTrigger"
|
||||||
:allow-clear="props.component.allowClear ?? true"
|
:allow-clear="props.component.allowClear ?? true"
|
||||||
@@ -43,6 +38,7 @@
|
|||||||
:show-time="props.component.showTime"
|
:show-time="props.component.showTime"
|
||||||
:preview-shortcut="props.component.previewShortcut"
|
:preview-shortcut="props.component.previewShortcut"
|
||||||
:show-confirm-btn="props.component.showConfirmBtn"
|
:show-confirm-btn="props.component.showConfirmBtn"
|
||||||
|
:type="props.component.range ? (props.component.formType === 'time' ? 'time-range' : 'range') : ''"
|
||||||
:time-picker-props="
|
:time-picker-props="
|
||||||
props.component.formType == 'range' ? { defaultValue: ['00:00:00', '23:59:59'] } : {}
|
props.component.formType == 'range' ? { defaultValue: ['00:00:00', '23:59:59'] } : {}
|
||||||
"
|
"
|
||||||
@@ -52,9 +48,9 @@
|
|||||||
@change="handlePickerChangeEvent"
|
@change="handlePickerChangeEvent"
|
||||||
@select="handlePickerSelectEvent"
|
@select="handlePickerSelectEvent"
|
||||||
@ok="handlePickerOkEvent"
|
@ok="handlePickerOkEvent"
|
||||||
@clear="maEvent.handleCommonEvent(props.component, 'onClear')"
|
@clear="rv('onClear')"
|
||||||
@popup-visible-change="maEvent.customeEvent(props.component, $event, 'onvVisibleChange')"
|
@popup-visible-change="rv('onvVisibleChange', $event)"
|
||||||
@select-shortcut="maEvent.customeEvent(props.component, $event, 'onSelectShortcut')"
|
@select-shortcut="rv('onSelectShortcut', $event)"
|
||||||
@picker-value-change="handlePickerValueChangeEvent"
|
@picker-value-change="handlePickerValueChangeEvent"
|
||||||
/>
|
/>
|
||||||
</slot>
|
</slot>
|
||||||
@@ -63,15 +59,19 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -94,23 +94,21 @@ const getComponentName = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handlePickerChangeEvent = (value, date, dateString) => {
|
const handlePickerChangeEvent = (value, date, dateString) => {
|
||||||
maEvent.handleChangeEvent(props.component, { value, date, dateString })
|
rv("onPickerChange", { value, date, dateString })
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePickerSelectEvent = (value, date, dateString) => {
|
const handlePickerSelectEvent = (value, date, dateString) => {
|
||||||
maEvent.customeEvent(props.component, { value, date, dateString }, "onSelect")
|
rv("onSelect", { value, date, dateString })
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePickerValueChangeEvent = (value, date, dateString) => {
|
const handlePickerValueChangeEvent = (value, date, dateString) => {
|
||||||
maEvent.customeEvent(props.component, { value, date, dateString }, "onPickerValueChange")
|
rv("onPickerValueChange", { value, date, dateString })
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePickerOkEvent = (value, date, dateString) => {
|
const handlePickerOkEvent = (value, date, dateString) => {
|
||||||
maEvent.customeEvent(props.component, { value, date, dateString }, "onOk")
|
rv("onOk", { value, date, dateString })
|
||||||
}
|
}
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -33,8 +28,8 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, nextTick, watch } from "vue"
|
import { ref, inject, onMounted, nextTick, watch } from "vue"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { get, set, isUndefined } from "lodash"
|
import { get, set, isUndefined } from "lodash-es"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
import { handlerCascader } from "../js/networkRequest.js"
|
import { handlerCascader } from "../js/networkRequest.js"
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -45,7 +40,10 @@ const props = defineProps({
|
|||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
const dictList = inject("dictList")
|
const dictList = inject("dictList")
|
||||||
const formLoading = inject("formLoading")
|
const formLoading = inject("formLoading")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
const columns = inject("columns")
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const dictIndex = index.match(/^(\w+\.)\d+\./)
|
const dictIndex = index.match(/^(\w+\.)\d+\./)
|
||||||
@@ -80,7 +78,7 @@ const handleCascaderChangeEvent = async (value) => {
|
|||||||
const component = props.component
|
const component = props.component
|
||||||
// 执行自定义事件
|
// 执行自定义事件
|
||||||
if (component.onChange) {
|
if (component.onChange) {
|
||||||
maEvent.handleChangeEvent(component, value)
|
rv("onChange", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理联动
|
// 处理联动
|
||||||
@@ -90,8 +88,6 @@ const handleCascaderChangeEvent = async (value) => {
|
|||||||
nextTick(() => (formLoading.value = false))
|
nextTick(() => (formLoading.value = false))
|
||||||
}
|
}
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -24,8 +19,8 @@
|
|||||||
:allow-half="props.component.allowHalf"
|
:allow-half="props.component.allowHalf"
|
||||||
:grading="props.component.grading"
|
:grading="props.component.grading"
|
||||||
:color="props.component.color"
|
:color="props.component.color"
|
||||||
@change="maEvent.handleInputEvent(props.component, $event)"
|
@change="rv('onChange', $event)"
|
||||||
@hover-change="maEvent.customeEvent(props.component, $event, 'onHoverChange')"
|
@hover-change="rv('onHoverChange', $event)"
|
||||||
>
|
>
|
||||||
</a-rate>
|
</a-rate>
|
||||||
</slot>
|
</slot>
|
||||||
@@ -34,15 +29,20 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -58,8 +58,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -34,17 +29,21 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaResource from "@/components/ma-resource/index.vue"
|
import MaResource from "@/components/ma-resource/index.vue"
|
||||||
import MaResourceButton from "@/components/ma-resource/button.vue"
|
import MaResourceButton from "@/components/ma-resource/button.vue"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -64,8 +63,6 @@ if (props.component.multiple && !value.value) {
|
|||||||
value.value = []
|
value.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -16,6 +11,7 @@
|
|||||||
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
||||||
<a-select
|
<a-select
|
||||||
v-model:model-value="value"
|
v-model:model-value="value"
|
||||||
|
:options="props.component.data ?? dictList[dictIndex] ?? []"
|
||||||
:multiple="props.component.multiple"
|
:multiple="props.component.multiple"
|
||||||
:size="props.component.size"
|
:size="props.component.size"
|
||||||
:allow-clear="props.component.allowClear ?? true"
|
:allow-clear="props.component.allowClear ?? true"
|
||||||
@@ -23,10 +19,10 @@
|
|||||||
:readonly="props.component.readonly"
|
:readonly="props.component.readonly"
|
||||||
:error="props.component.error"
|
:error="props.component.error"
|
||||||
:placeholder="props.component.placeholder ?? `请选择${props.component.title}`"
|
:placeholder="props.component.placeholder ?? `请选择${props.component.title}`"
|
||||||
:loading="props.component.loading"
|
:loading="props.component.loading ?? loading"
|
||||||
:allow-search="props.component.allowSearch ?? true"
|
:allow-search="props.component.allowSearch ?? true"
|
||||||
:allow-create="props.component.allowCreate"
|
:allow-create="props.component.allowCreate"
|
||||||
:max-tag-count="props.component.maxTagCount"
|
:max-tag-count="props.component.maxTagCount ?? 1"
|
||||||
:bordered="props.component.bordered"
|
:bordered="props.component.bordered"
|
||||||
:unmount-on-close="props.component.unmountOnClose"
|
:unmount-on-close="props.component.unmountOnClose"
|
||||||
:popup-container="props.component.popupContainer"
|
:popup-container="props.component.popupContainer"
|
||||||
@@ -34,39 +30,100 @@
|
|||||||
:virtual-list-props="props.component.virtualListProps"
|
:virtual-list-props="props.component.virtualListProps"
|
||||||
:trigger-props="props.component.triggerProps"
|
:trigger-props="props.component.triggerProps"
|
||||||
:format-label="props.component.formatLabel"
|
:format-label="props.component.formatLabel"
|
||||||
:fallback-option="props.component.fallbackOption"
|
:fallback-option="props.component.fallbackOption ?? handlerFallback"
|
||||||
:show-extra-options="props.component.showExtraOptions"
|
:show-extra-options="props.component.showExtraOptions ?? false"
|
||||||
:value-key="props.component.valueKey"
|
:value-key="props.component.valueKey"
|
||||||
:search-delay="props.component.searchDelay"
|
:search-delay="props.component.searchDelay"
|
||||||
:limit="props.component.limit"
|
:limit="props.component.limit"
|
||||||
:field-names="props.component.fieldNames"
|
:field-names="props.component.fieldNames"
|
||||||
:scrollbar="props.component.scrollbar"
|
:scrollbar="props.component.scrollbar"
|
||||||
@input-value-change="maEvent.handleInputEvent(props.component, $event)"
|
@input-value-change="rv('onInputValueChange', $event)"
|
||||||
@change="handleCascaderChangeEvent($event)"
|
@change="handleCascaderChangeEvent($event)"
|
||||||
@remove="maEvent.customeEvent(props.component, $event, 'onRemove')"
|
@remove="rv('onRemove', $event)"
|
||||||
@popup-visible-change="maEvent.customeEvent(props.component, $event, 'onPopupVisibleChange')"
|
@popup-visible-change="rv('onPopupVisibleChange', $event)"
|
||||||
@dropdown-scroll="maEvent.handleCommonEvent(props.component, 'onDropdownScroll')"
|
@dropdown-scroll="rv('onDropdownScroll')"
|
||||||
@dropdown-reach-bottom="maEvent.handleCommonEvent(props.component, 'onDropdownReachBottom')"
|
@dropdown-reach-bottom="rv('onDropdownReachBottom')"
|
||||||
@exceed-limit="maEvent.customeEvent(props.component, $event, 'onExceedLimit')"
|
@exceed-limit="rv('onExceedLimit', $event)"
|
||||||
@clear="maEvent.handleCommonEvent(props.component, 'onClear')"
|
@search="rv('onSearch', $event)"
|
||||||
@focus="maEvent.handleCommonEvent(props.component, 'onFocus')"
|
|
||||||
@blur="maEvent.handleCommonEvent(props.component, 'onBlur')"
|
|
||||||
@search="maEvent.customeEvent(props.component, $event, 'onSearch')"
|
|
||||||
>
|
>
|
||||||
<template v-for="(item, index) in dictList[dictIndex] ?? []">
|
<template #header v-if="props.component.multiple && props.component.multipleTools">
|
||||||
<a-option :value="item.value" :disabled="item.disabled">{{ item.label }}</a-option>
|
|
||||||
</template>
|
|
||||||
<template #header v-if="props.component.multiple">
|
|
||||||
<div style="padding: 6px 12px">
|
<div style="padding: 6px 12px">
|
||||||
<a-space>
|
<a-space fill>
|
||||||
<a-checkbox :value="false" @change="handleSelectAll">全选/清除</a-checkbox>
|
<a-checkbox
|
||||||
<a-button size="mini" type="outline" @click="handleInverse">反选</a-button>
|
v-if="
|
||||||
|
isBoolean(props.component.multipleTools) || props.component.multipleTools.selectAll
|
||||||
|
"
|
||||||
|
:model-value="checkedAll"
|
||||||
|
:indeterminate="indeterminate"
|
||||||
|
:disabled="loading"
|
||||||
|
@change="handleSelectAll"
|
||||||
|
>全选/清除</a-checkbox
|
||||||
|
>
|
||||||
|
|
||||||
|
<a-button
|
||||||
|
v-if="isBoolean(props.component.multipleTools) || props.component.multipleTools.inverse"
|
||||||
|
class="ml-2"
|
||||||
|
size="mini"
|
||||||
|
type="outline"
|
||||||
|
:disabled="loading"
|
||||||
|
@click="handleInverse"
|
||||||
|
>反选</a-button
|
||||||
|
>
|
||||||
|
|
||||||
|
<a-popover
|
||||||
|
:content-style="{ padding: '0px', width: '256px' }"
|
||||||
|
position="rt"
|
||||||
|
trigger="click"
|
||||||
|
v-if="
|
||||||
|
isBoolean(props.component.multipleTools) ||
|
||||||
|
props.component.multipleTools.showSelectAll
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a-button class="ml-2" size="mini">已选 {{ value.length }}</a-button>
|
||||||
|
<template #title>
|
||||||
|
<a-space fill style="padding: 12px 12px 8px 12px">
|
||||||
|
<a-button
|
||||||
|
:disabled="loading || !value.length"
|
||||||
|
size="mini"
|
||||||
|
status="danger"
|
||||||
|
@click="value = []"
|
||||||
|
>清空 {{ value.length }}</a-button
|
||||||
|
>
|
||||||
|
<a-input-search v-model="keyword" size="mini" allow-clear />
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<a-scrollbar style="height: 200px; overflow: auto">
|
||||||
|
<a-checkbox-group
|
||||||
|
v-if="
|
||||||
|
(value.length && keyword === '') ||
|
||||||
|
Object.keys(filteredOptions).length > 0
|
||||||
|
"
|
||||||
|
direction="vertical"
|
||||||
|
v-model="value"
|
||||||
|
>
|
||||||
|
<div v-for="item in filteredOptions" class="select-all-options">
|
||||||
|
<a-checkbox :value="item.value">{{ item.label }}</a-checkbox>
|
||||||
|
</div>
|
||||||
|
</a-checkbox-group>
|
||||||
|
<a-empty v-else />
|
||||||
|
</a-scrollbar>
|
||||||
|
</template>
|
||||||
|
</a-popover>
|
||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #footer v-if="props.component?.dict.pageOption ?? false">
|
<template #footer v-if="props.component?.dict?.openPage ?? false">
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<a-pagination class="p-2" size="mini" :total="200" simple>
|
<a-pagination
|
||||||
|
class="p-2"
|
||||||
|
size="mini"
|
||||||
|
:total="dataTotal"
|
||||||
|
:page-size="props.component.dict.pageOption.pageSize"
|
||||||
|
:disabled="loading"
|
||||||
|
simple
|
||||||
|
@change="handlePage"
|
||||||
|
>
|
||||||
<template #page-item-step="{ type }">
|
<template #page-item-step="{ type }">
|
||||||
<div>{{ type === "previous" ? "上一页" : "下一页" }}</div>
|
<div>{{ type === "previous" ? "上一页" : "下一页" }}</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -79,27 +136,41 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, nextTick, watch } from "vue"
|
import { ref, inject, onMounted, nextTick, watch, computed } from "vue"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { get, isUndefined, set, xor } from "lodash"
|
import { get, isUndefined, set, xor, isObject, isBoolean } from "lodash-es"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
import { handlerCascader } from "../js/networkRequest.js"
|
import { handlerCascader, loadDict } from "../js/networkRequest.js"
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (isObject(props.component.dict)) {
|
||||||
|
props.component.dict.pageOption = {
|
||||||
|
page: 1,
|
||||||
|
pageSize: props.component?.dict?.pageOption?.pageSize ?? props.component?.dict?.pageSize ?? 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
const dictList = inject("dictList")
|
const dictList = inject("dictList")
|
||||||
const formLoading = inject("formLoading")
|
const formLoading = inject("formLoading")
|
||||||
const columns = inject("columns")
|
const columns = inject("columns")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const rv = async (ev, value = "") =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const dictIndex = index.match(/^(\w+\.)\d+\./)
|
const dictIndex = index.match(/^(\w+\.)\d+\./)
|
||||||
? index.match(/^(\w+\.)\d+\./)[1] + props.component.dataIndex
|
? index.match(/^(\w+\.)\d+\./)[1] + props.component.dataIndex
|
||||||
: props.component.dataIndex
|
: props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index, ""))
|
const value = ref(get(formModel.value, index, ""))
|
||||||
|
const dataTotal = ref(0)
|
||||||
|
const loading = ref(false)
|
||||||
|
const optionMap = ref({})
|
||||||
|
const keyword = ref("")
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => get(formModel.value, index),
|
() => get(formModel.value, index),
|
||||||
@@ -108,13 +179,57 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => value.value,
|
() => value.value,
|
||||||
(v) => {
|
(v) => {
|
||||||
|
if (props.component.multiple) {
|
||||||
|
v.forEach((k) => {
|
||||||
|
if (!optionMap.value[k]) {
|
||||||
|
optionMap.value[k] = dictList.value[dictIndex].find((i) => i.value === k)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
for (const k in optionMap.value) {
|
||||||
|
if (!v.includes(k)) delete optionMap.value[k]
|
||||||
|
}
|
||||||
|
}
|
||||||
set(formModel.value, index, v)
|
set(formModel.value, index, v)
|
||||||
index.indexOf(".") > -1 && delete formModel.value[index]
|
index.indexOf(".") > -1 && delete formModel.value[index]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
watch(
|
||||||
|
() => dictList.value[index],
|
||||||
|
async (v) => {
|
||||||
|
dataTotal.value = v?.pageInfo?.total || 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const checkedAll = computed(() => {
|
||||||
|
const { multiple, multipleTools } = props.component
|
||||||
|
const currentDicts = dictList.value[dictIndex]
|
||||||
|
|
||||||
|
if (multiple && multipleTools && currentDicts) {
|
||||||
|
return currentDicts.every((item) => value.value.includes(item.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
const filteredOptions = computed(() => {
|
||||||
|
const { multiple, multipleTools } = props.component
|
||||||
|
if (multiple && multipleTools && keyword.value !== "") {
|
||||||
|
const lowerCaseKeyword = keyword.value.toLowerCase()
|
||||||
|
return Object.values(optionMap.value).filter((option) => option.label.toLowerCase().includes(lowerCaseKeyword))
|
||||||
|
}
|
||||||
|
return optionMap.value
|
||||||
|
})
|
||||||
|
|
||||||
|
const indeterminate = computed(() => {
|
||||||
|
if (props.component.multiple && props.component.multipleTools && checkedAll.value == false) {
|
||||||
|
const currentDicts = dictList.value[dictIndex]
|
||||||
|
return currentDicts.some((item) => value.value.includes(item.value))
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
if (value.value === "") {
|
if (value.value === "") {
|
||||||
value.value = undefined
|
value.value = props.component.multiple === true ? [] : ""
|
||||||
} else if (
|
} else if (
|
||||||
!isUndefined(value.value) &&
|
!isUndefined(value.value) &&
|
||||||
props.component.dict &&
|
props.component.dict &&
|
||||||
@@ -124,14 +239,17 @@ if (value.value === "") {
|
|||||||
value.value = value.value + ""
|
value.value = value.value + ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isUndefined(props.component.multipleTools)) props.component.multipleTools = true
|
||||||
const handleSelectAll = (status) => {
|
const handleSelectAll = (status) => {
|
||||||
if (isUndefined(value.value)) {
|
if (isUndefined(value.value)) {
|
||||||
value.value = []
|
value.value = []
|
||||||
}
|
}
|
||||||
if (status) {
|
if (status) {
|
||||||
dictList.value[dictIndex].map((item) => {
|
const currentSet = new Set(value.value)
|
||||||
value.value.push(item.value)
|
const newValues = dictList.value[dictIndex]
|
||||||
})
|
.filter((item) => !currentSet.has(item.value))
|
||||||
|
.map((item) => item.value)
|
||||||
|
value.value = [...value.value, ...newValues]
|
||||||
} else {
|
} else {
|
||||||
value.value = []
|
value.value = []
|
||||||
}
|
}
|
||||||
@@ -143,15 +261,25 @@ const handleInverse = () => {
|
|||||||
}
|
}
|
||||||
const ids = []
|
const ids = []
|
||||||
dictList.value[dictIndex].map((item) => ids.push(item.value))
|
dictList.value[dictIndex].map((item) => ids.push(item.value))
|
||||||
value.value = xor(ids, value.value)
|
value.value = xor(value.value, ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handlePage = async (page) => {
|
||||||
|
loading.value = true
|
||||||
|
props.component.dict.pageOption.page = page
|
||||||
|
await loadDict(dictList.value, props.component)
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlerFallback = (key) => {
|
||||||
|
return optionMap.value[key] || key
|
||||||
|
}
|
||||||
const handleCascaderChangeEvent = async (value) => {
|
const handleCascaderChangeEvent = async (value) => {
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
const component = props.component
|
const component = props.component
|
||||||
// 执行自定义事件
|
// 执行自定义事件
|
||||||
if (component.onChange) {
|
if (component.onChange) {
|
||||||
maEvent.handleChangeEvent(component, value)
|
rv("onChange", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理联动
|
// 处理联动
|
||||||
@@ -161,8 +289,30 @@ const handleCascaderChangeEvent = async (value) => {
|
|||||||
nextTick(() => (formLoading.value = false))
|
nextTick(() => (formLoading.value = false))
|
||||||
}
|
}
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => {})
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.arco-checkbox-group {
|
||||||
|
width: 100%;
|
||||||
|
.select-all-options {
|
||||||
|
width: 100%;
|
||||||
|
height: 36px;
|
||||||
|
padding: 0 15px 0 7px;
|
||||||
|
color: inherit;
|
||||||
|
background-color: transparent;
|
||||||
|
transition: all 0.1s cubic-bezier(0, 0, 1, 1);
|
||||||
|
::v-deep(.arco-checkbox .arco-checkbox-label) {
|
||||||
|
height: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-text-1);
|
||||||
|
background-color: var(--color-fill-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
601
cdTMP/src/components/ma-form/formItem/form-sku.vue
Normal file
601
cdTMP/src/components/ma-form/formItem/form-sku.vue
Normal file
@@ -0,0 +1,601 @@
|
|||||||
|
<template>
|
||||||
|
<ma-form-item
|
||||||
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
|
:component="props.component"
|
||||||
|
:custom-field="props.customField"
|
||||||
|
>
|
||||||
|
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
||||||
|
<div style="flex: 1 1 auto" class="arco-col arco-form-item-wrapper-col">
|
||||||
|
<div class="add-spec">
|
||||||
|
<a-button type="primary" :disabled="specification.length >= 5" @click="addSpec">添加规格</a-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 10px; width: 100%; height: auto">
|
||||||
|
<div class="specification">
|
||||||
|
<ul class="spec-list" v-if="specification.length">
|
||||||
|
<li class="item" v-for="(item, index) in specification" :key="index">
|
||||||
|
<div class="name">
|
||||||
|
<a-input placeholder="输入产品规格" allow-clear v-model="item.name" />
|
||||||
|
<i class="icon el-icon-circle-close" @click="delSpec(index)"></i>
|
||||||
|
</div>
|
||||||
|
<div class="values" style="display: flex">
|
||||||
|
<div style="margin-bottom: 5px">
|
||||||
|
<span
|
||||||
|
class="el-tag"
|
||||||
|
v-for="(tag, num) in item.value"
|
||||||
|
:key="tag"
|
||||||
|
style="margin: 15px 5px"
|
||||||
|
>
|
||||||
|
<a-tag closable @close="delSpecTag(index, num)">{{ tag }}</a-tag>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="add-attr" style="margin: 0 0 0 5px">
|
||||||
|
<div style="display: flex">
|
||||||
|
<a-input
|
||||||
|
style="width: 120px"
|
||||||
|
allow-clear
|
||||||
|
size="small"
|
||||||
|
v-model="addValues[index]"
|
||||||
|
placeholder="请输入规格值"
|
||||||
|
/>
|
||||||
|
<a-button
|
||||||
|
type="primary"
|
||||||
|
size="mini"
|
||||||
|
@click="addSpecTag(index)"
|
||||||
|
style="margin-left: 5px"
|
||||||
|
>确定</a-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<table class="stock-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th v-for="(item, index) in specification" :key="index">
|
||||||
|
{{ item.name }}
|
||||||
|
</th>
|
||||||
|
<th style="width: 160px">规格编码</th>
|
||||||
|
<th>成本价(元)</th>
|
||||||
|
<th>库存</th>
|
||||||
|
<th>销售价(元)</th>
|
||||||
|
<th>是否启用</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody v-if="specification[0] && specification[0].value.length">
|
||||||
|
<tr :key="index" v-for="(item, index) in countSum(0)">
|
||||||
|
<template v-for="(n, specIndex) in specification.length">
|
||||||
|
<td v-if="showTda(specIndex, index)" :key="n" :rowspan="countSum(n)">
|
||||||
|
{{ getSpecAttr(specIndex, index) }}
|
||||||
|
</td>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<a-input
|
||||||
|
type="text"
|
||||||
|
:disabled="!childProductArray[index].isUse"
|
||||||
|
v-model="childProductArray[index].childProductNo"
|
||||||
|
@blur="handleNo(index)"
|
||||||
|
placeholder="输入商品规格编号"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a-input
|
||||||
|
type="text"
|
||||||
|
v-model.number="childProductArray[index].childProductCost"
|
||||||
|
placeholder="输入成本价"
|
||||||
|
:disabled="!childProductArray[index].isUse"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a-input
|
||||||
|
type="text"
|
||||||
|
v-model.number="childProductArray[index].childProductStock"
|
||||||
|
placeholder="输入库存"
|
||||||
|
:disabled="!childProductArray[index].isUse"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a-input
|
||||||
|
type="text"
|
||||||
|
v-model.number="childProductArray[index].childProductPrice"
|
||||||
|
placeholder="输入销售价"
|
||||||
|
:disabled="!childProductArray[index].isUse"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a-switch
|
||||||
|
v-model="childProductArray[index].isUse"
|
||||||
|
size="small"
|
||||||
|
@change="
|
||||||
|
(val) => {
|
||||||
|
handleUserChange(index, val)
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="8" class="wh-foot">
|
||||||
|
<span class="label">批量设置:</span>
|
||||||
|
<ul class="set-list" v-if="isSetListShow">
|
||||||
|
<li class="set-item" @click="openBatch('childProductCost')">成本价</li>
|
||||||
|
<li class="set-item" @click="openBatch('childProductStock')">库存</li>
|
||||||
|
<li class="set-item" @click="openBatch('childProductPrice')">销售价</li>
|
||||||
|
</ul>
|
||||||
|
<div class="set-form" v-else>
|
||||||
|
<a-input-number
|
||||||
|
v-model="batchValue"
|
||||||
|
placeholder="输入要设置的数量"
|
||||||
|
class="input-demo"
|
||||||
|
:min="1"
|
||||||
|
:max="99999"
|
||||||
|
/>
|
||||||
|
<a-button
|
||||||
|
style="margin-right: 5px"
|
||||||
|
type="primary"
|
||||||
|
@click="setBatch"
|
||||||
|
size="mini"
|
||||||
|
>确定</a-button
|
||||||
|
>
|
||||||
|
<a-button type="primary" @click="cancelBatch" size="mini">取消</a-button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div class="example">-->
|
||||||
|
<!-- <h4 class="title">数据格式</h4>-->
|
||||||
|
<!-- <textarea class="code-area" :value="JSON.stringify(childProductArray)"></textarea>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
</slot>
|
||||||
|
</ma-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// 引入相关vue必要的api
|
||||||
|
import { inject, onMounted, reactive, ref, watch } from "vue"
|
||||||
|
// 引入处理索引的函数
|
||||||
|
import { get, set } from "lodash-es"
|
||||||
|
// 引入 MaFormItem 组件
|
||||||
|
import MaFormItem from "./form-item.vue"
|
||||||
|
// 引入处理事件的函数
|
||||||
|
import { runEvent } from "../js/event.js"
|
||||||
|
|
||||||
|
// 组件都需要定义以下的props
|
||||||
|
const props = defineProps({
|
||||||
|
component: Object,
|
||||||
|
customField: { type: String, default: undefined }
|
||||||
|
})
|
||||||
|
|
||||||
|
// 该组件在form数据的索引名称
|
||||||
|
const index = props.customField ?? props.component.dataIndex
|
||||||
|
|
||||||
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
|
// 规格
|
||||||
|
let specification = reactive([])
|
||||||
|
|
||||||
|
let addValues = reactive([])
|
||||||
|
|
||||||
|
let isSetListShow = ref(true)
|
||||||
|
let batchValue = ref(1)
|
||||||
|
|
||||||
|
let currentType = ref("")
|
||||||
|
|
||||||
|
let defaultProductNo = "P_"
|
||||||
|
|
||||||
|
let childProductArray = reactive([])
|
||||||
|
|
||||||
|
childProductArray = value.value && value.value.sku ? value.value.sku : reactive([])
|
||||||
|
specification = value.value && value.value.spec ? value.value.spec : reactive([])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
return childProductArray.map((item) => item.childProductSpec)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听组件数据的改变
|
||||||
|
watch(
|
||||||
|
() => addValues,
|
||||||
|
(vl) => {
|
||||||
|
value.value = vl
|
||||||
|
|
||||||
|
let json = {
|
||||||
|
sku: childProductArray,
|
||||||
|
spec: specification
|
||||||
|
}
|
||||||
|
|
||||||
|
set(formModel.value, index, json)
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => specification,
|
||||||
|
(v) => {
|
||||||
|
let json = {
|
||||||
|
sku: childProductArray,
|
||||||
|
spec: specification
|
||||||
|
}
|
||||||
|
|
||||||
|
set(formModel.value, index, json)
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => childProductArray,
|
||||||
|
(v) => {
|
||||||
|
let json = {
|
||||||
|
sku: childProductArray,
|
||||||
|
spec: specification
|
||||||
|
}
|
||||||
|
|
||||||
|
set(formModel.value, index, json)
|
||||||
|
// set(formModel.value, index, v)
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 打开设置框
|
||||||
|
function openBatch(type) {
|
||||||
|
currentType.value = type
|
||||||
|
isSetListShow.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量设置
|
||||||
|
function setBatch() {
|
||||||
|
if (typeof batchValue.value === "string") {
|
||||||
|
alert("请输入正确的值")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
childProductArray.forEach((item) => {
|
||||||
|
if (item.isUse) {
|
||||||
|
item[currentType.value] = batchValue.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
cancelBatch()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消批量设置
|
||||||
|
function cancelBatch() {
|
||||||
|
batchValue.value = 1
|
||||||
|
currentType.value = ""
|
||||||
|
isSetListShow.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听规格启用操作
|
||||||
|
function handleUserChange(index, value) {
|
||||||
|
// 启用规格时,生成不重复的商品编号;关闭规格时,清空商品编号
|
||||||
|
if (value) {
|
||||||
|
childProductArray[index].childProductNo = makeProductNoNotRepet(index)
|
||||||
|
} else {
|
||||||
|
childProductArray[index].childProductNo = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听商品编号的blur事件
|
||||||
|
function handleNo(index, attr) {
|
||||||
|
// 1.当用户输入完商品编号时,判断是否重复,如有重复,则提示客户并自动修改为不重复的商品编号
|
||||||
|
const value = childProductArray[index].childProductNo
|
||||||
|
let isRepet
|
||||||
|
|
||||||
|
childProductArray.forEach((item, i) => {
|
||||||
|
if (item.childProductNo === value && i !== index) {
|
||||||
|
isRepet = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (isRepet) {
|
||||||
|
alert("不允许输入重复的商品编号")
|
||||||
|
|
||||||
|
childProductArray[index].childProductNo = makeProductNoNotRepet(index)
|
||||||
|
// this.$set(this.childProductArray[index], 'childProductNo', this.)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成不重复的商品编号
|
||||||
|
function makeProductNoNotRepet(index) {
|
||||||
|
let No
|
||||||
|
let i = index
|
||||||
|
let isRepet = true
|
||||||
|
while (isRepet) {
|
||||||
|
No = defaultProductNo + i
|
||||||
|
isRepet = isProductNoRepet(No)
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return No
|
||||||
|
}
|
||||||
|
|
||||||
|
// 商品编号判重
|
||||||
|
function isProductNoRepet(No) {
|
||||||
|
const result = childProductArray.findIndex((item) => {
|
||||||
|
return item.childProductNo === No
|
||||||
|
})
|
||||||
|
return result > -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据传入的条件,来判断是否显示该td
|
||||||
|
function showTda(specIndex, index) {
|
||||||
|
// 如果当前项目下没有属性,则不显示
|
||||||
|
if (!specification[specIndex]) {
|
||||||
|
return false
|
||||||
|
|
||||||
|
// 自己悟一下吧
|
||||||
|
} else if (index % countSum(specIndex + 1) === 0) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加规格属性
|
||||||
|
function addSpecTag(index) {
|
||||||
|
let str = addValues[index] || ""
|
||||||
|
if (!str.trim()) return // 判空
|
||||||
|
str = str.trim()
|
||||||
|
let arr = str.split(/\s+/) // 使用空格分割成数组
|
||||||
|
|
||||||
|
let newArr = specification[index].value.concat(arr)
|
||||||
|
newArr = Array.from(new Set(newArr)) // 去重
|
||||||
|
|
||||||
|
specification[index].value = newArr
|
||||||
|
clearAddValues(index)
|
||||||
|
handleSpecChange("add")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空 addValues
|
||||||
|
function clearAddValues(index) {
|
||||||
|
addValues[index] = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除规格属性
|
||||||
|
function delSpecTag(index, num) {
|
||||||
|
specification[index].value.splice(num, 1)
|
||||||
|
|
||||||
|
handleSpecChange("del")
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSpec() {
|
||||||
|
if (specification.length < 5) {
|
||||||
|
specification.push({
|
||||||
|
name: "",
|
||||||
|
value: []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function delSpec(index) {
|
||||||
|
specification.splice(index, 1)
|
||||||
|
handleSpecChange("del")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [handleSpecChange 监听标签的变化,当添加标签时;求出每一行的hash id,再动态变更库存信息;当删除标签时,先清空已有库存信息,然后将原有库存信息暂存到stockCopy中,方便后面调用]
|
||||||
|
* @param {[string]} option ['add'|'del' 操作类型,添加或删除]
|
||||||
|
* @return {[type]} [description]
|
||||||
|
*/
|
||||||
|
function handleSpecChange(option) {
|
||||||
|
const stockCopy = JSON.parse(JSON.stringify(childProductArray))
|
||||||
|
if (option === "del") {
|
||||||
|
childProductArray = []
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < countSum(0); i++) {
|
||||||
|
changeStock(option, i, stockCopy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取childProductArray的childProductSpec属性
|
||||||
|
function getChildProductSpec(index) {
|
||||||
|
let obj = {}
|
||||||
|
specification.forEach((item, specIndex) => {
|
||||||
|
obj[item.name] = getSpecAttr(specIndex, index)
|
||||||
|
})
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
根据传入的属性值,拿到相应规格的属性
|
||||||
|
@params
|
||||||
|
specIndex 规格项目在 advancedSpecification 中的序号
|
||||||
|
index 所有属性在遍历时的序号
|
||||||
|
*/
|
||||||
|
function getSpecAttr(specIndex, index) {
|
||||||
|
// 获取当前规格项目下的属性值
|
||||||
|
const currentValues = specification[specIndex].value
|
||||||
|
let indexCopy
|
||||||
|
|
||||||
|
// 判断是否是最后一个规格项目
|
||||||
|
if (specification[specIndex + 1] && specification[specIndex + 1].value.length) {
|
||||||
|
indexCopy = index / countSum(specIndex + 1)
|
||||||
|
} else {
|
||||||
|
indexCopy = index
|
||||||
|
}
|
||||||
|
|
||||||
|
const i = Math.floor(indexCopy % currentValues.length)
|
||||||
|
|
||||||
|
if (i.toString() !== "NaN") {
|
||||||
|
return currentValues[i]
|
||||||
|
} else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [根据规格,动态改变库存相关信息]
|
||||||
|
* @param {[string]} option ['add'|'del' 操作类型,添加或删除]
|
||||||
|
* @param {[array]} stockCopy [库存信息的拷贝]
|
||||||
|
* @return {[type]} [description]
|
||||||
|
*/
|
||||||
|
function changeStock(option, index, stockCopy) {
|
||||||
|
let childProduct = {
|
||||||
|
childProductId: 0,
|
||||||
|
childProductSpec: getChildProductSpec(index),
|
||||||
|
childProductNo: defaultProductNo + index,
|
||||||
|
childProductStock: 0,
|
||||||
|
childProductPrice: 0,
|
||||||
|
childProductCost: 0,
|
||||||
|
isUse: true
|
||||||
|
}
|
||||||
|
|
||||||
|
const spec = childProduct.childProductSpec
|
||||||
|
if (option === "add") {
|
||||||
|
// 如果此id不存在,说明为新增属性,则向 childProductArray 中添加一条数据
|
||||||
|
// if (stockSpecArr.value.findIndex((item) => objEquals(spec, item)) === -1) {
|
||||||
|
childProductArray[index] = childProduct
|
||||||
|
// }
|
||||||
|
} else if (option === "del") {
|
||||||
|
// 因为是删除操作,理论上所有数据都能从stockCopy中获取到
|
||||||
|
let origin = ""
|
||||||
|
stockCopy.forEach((item) => {
|
||||||
|
if (objEquals(spec, item.childProductSpec)) {
|
||||||
|
origin = item
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
childProductArray.push(origin || childProduct)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function objEquals(aObj, bObj) {
|
||||||
|
if (typeof aObj == "object" && typeof bObj == "object") {
|
||||||
|
if (aObj.constructor == Array && bObj.constructor == Array) {
|
||||||
|
return aObj.length == bObj.length && JSON.stringify(aObj) == JSON.stringify(bObj)
|
||||||
|
} else {
|
||||||
|
return Object.keys(aObj) == Object.keys(bObj) && Object.values(aObj) == Object.values(bObj)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return aObj === bObj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
计算属性的乘积
|
||||||
|
@params
|
||||||
|
specIndex 规格项目在 advancedSpecification 中的序号
|
||||||
|
*/
|
||||||
|
function countSum(specIndex) {
|
||||||
|
let num = 1
|
||||||
|
specification.forEach((item, index) => {
|
||||||
|
if (index >= specIndex && item.value.length) {
|
||||||
|
num *= item.value.length
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
// 绑定组件事件
|
||||||
|
rv("onCreated")
|
||||||
|
onMounted(() => rv("onMounted"))
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "form-sku"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.specification {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specification .spec-list {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #d8d8d8;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specification .spec-list .item {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specification .spec-list .item:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specification .spec-list .item .name {
|
||||||
|
/*background: #f3f6fb;*/
|
||||||
|
padding: 2px 8px;
|
||||||
|
text-align: right;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specification .spec-list .item .name .icon {
|
||||||
|
display: none;
|
||||||
|
color: #929292;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specification .spec-list .item .name .icon:hover {
|
||||||
|
color: #880000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stock-table td,
|
||||||
|
.stock-table th {
|
||||||
|
padding: 4px 10px;
|
||||||
|
border-bottom: 1px solid #dfe6ec;
|
||||||
|
border-right: 1px solid #dfe6ec;
|
||||||
|
border-left: 1px solid #dfe6ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stock-table th {
|
||||||
|
line-height: 30px;
|
||||||
|
background-color: #eef1f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stock-table .wh-foot {
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
.stock-table .wh-foot .label {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
.stock-table .wh-foot .set-list {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
font-size: 0;
|
||||||
|
}
|
||||||
|
.stock-table .wh-foot .set-list .set-item {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
margin-left: 15px;
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #0088ee;
|
||||||
|
}
|
||||||
|
.stock-table .wh-foot .set-form {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -28,7 +23,7 @@
|
|||||||
:marks="props.component.marks"
|
:marks="props.component.marks"
|
||||||
:show-input="props.component.showInput"
|
:show-input="props.component.showInput"
|
||||||
:show-ticks="props.component.showTicks"
|
:show-ticks="props.component.showTicks"
|
||||||
@change="maEvent.handleChangeEvent(props.component, $event)"
|
@change="rv('onChange', $event)"
|
||||||
>
|
>
|
||||||
</a-slider>
|
</a-slider>
|
||||||
</slot>
|
</slot>
|
||||||
@@ -37,15 +32,19 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -61,8 +60,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,33 +1,34 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
<div>
|
||||||
<div
|
<slot :name="`form-${props.component.dataIndex}`" v-bind="props.component">
|
||||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
<div
|
||||||
:class="['static-text', props.component.customClass]"
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
:style="props.component.style"
|
:class="['static-text', props.component.customClass]"
|
||||||
>
|
:style="props.component.style"
|
||||||
{{ props.component.title ?? "" }}
|
>
|
||||||
</div>
|
{{ props.component.title ?? "" }}
|
||||||
</slot>
|
</div>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted } from "vue"
|
import { onMounted, inject } from "vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object
|
component: Object
|
||||||
})
|
})
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
const formModel = inject("formModel")
|
||||||
onMounted(() => {
|
const getColumnService = inject("getColumnService")
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
const columns = inject("columns")
|
||||||
})
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
|
rv("onCreated")
|
||||||
|
onMounted(() => rv("onMounted"))
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
@@ -16,9 +20,9 @@
|
|||||||
:checked-color="props.component.checkedColor"
|
:checked-color="props.component.checkedColor"
|
||||||
:unchecked-color="props.component.uncheckedColor"
|
:unchecked-color="props.component.uncheckedColor"
|
||||||
:before-change="props.component.beforeChange"
|
:before-change="props.component.beforeChange"
|
||||||
@change="maEvent.handleChangeEvent(props.component, $event)"
|
@change="rv('onChange', $event)"
|
||||||
@focus="maEvent.handleCommonEvent(props.component, 'onFocus')"
|
@focus="rv('onFocus')"
|
||||||
@blur="maEvent.handleCommonEvent(props.component, 'onBlur')"
|
@blur="rv('onBlur')"
|
||||||
>
|
>
|
||||||
<template #checked>
|
<template #checked>
|
||||||
<slot :name="`switchChecked-${props.component.dataIndex}`" />
|
<slot :name="`switchChecked-${props.component.dataIndex}`" />
|
||||||
@@ -39,15 +43,20 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -63,8 +72,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,12 +1,3 @@
|
|||||||
<!--
|
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
@@ -27,11 +18,11 @@
|
|||||||
:show-word-limit="props.component.showWordLimit"
|
:show-word-limit="props.component.showWordLimit"
|
||||||
:word-length="props.component.wordLength"
|
:word-length="props.component.wordLength"
|
||||||
:word-slice="props.component.wordSlice"
|
:word-slice="props.component.wordSlice"
|
||||||
@input="maEvent.handleInputEvent(props.component, $event)"
|
@input="rv('onInput', $event)"
|
||||||
@change="maEvent.handleChangeEvent(props.component, $event)"
|
@change="rv('onChange', $event)"
|
||||||
@clear="maEvent.handleCommonEvent(props.component, 'onClear')"
|
@clear="rv('onClear')"
|
||||||
@focus="maEvent.handleCommonEvent(props.component, 'onFocus')"
|
@focus="rv('onFocus')"
|
||||||
@blur="maEvent.handleCommonEvent(props.component, 'onBlur')"
|
@blur="rv('onBlur')"
|
||||||
>
|
>
|
||||||
</a-textarea>
|
</a-textarea>
|
||||||
</slot>
|
</slot>
|
||||||
@@ -40,15 +31,20 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
|
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -64,8 +60,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -23,8 +18,8 @@
|
|||||||
:simple="props.component.simple"
|
:simple="props.component.simple"
|
||||||
:data="props.component.data ?? dictList[dictIndex] ?? []"
|
:data="props.component.data ?? dictList[dictIndex] ?? []"
|
||||||
:fallback="props.component.fallback"
|
:fallback="props.component.fallback"
|
||||||
@change="maEvent.handleChangeEvent(props.component, $event)"
|
@change="rv('onChange', $event)"
|
||||||
@select="maEvent.customeEvent(props.component, $event, 'onSelect')"
|
@select="rv('onSelect', $event)"
|
||||||
>
|
>
|
||||||
</a-transfer>
|
</a-transfer>
|
||||||
</slot>
|
</slot>
|
||||||
@@ -33,9 +28,9 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
@@ -43,7 +38,11 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
const dictList = inject("dictList")
|
const dictList = inject("dictList")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const dictIndex = index.match(/^(\w+\.)\d+\./)
|
const dictIndex = index.match(/^(\w+\.)\d+\./)
|
||||||
? index.match(/^(\w+\.)\d+\./)[1] + props.component.dataIndex
|
? index.match(/^(\w+\.)\d+\./)[1] + props.component.dataIndex
|
||||||
@@ -66,8 +65,6 @@ if (props.component.dict && (props.component.dict.name || props.component.dict.d
|
|||||||
value.value = value.value + ""
|
value.value = value.value + ""
|
||||||
}
|
}
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -48,10 +43,10 @@
|
|||||||
:fallback-option="props.component.fallbackOption"
|
:fallback-option="props.component.fallbackOption"
|
||||||
:selectable="props.component.selectable"
|
:selectable="props.component.selectable"
|
||||||
:scrollbar="props.component.scrollbar"
|
:scrollbar="props.component.scrollbar"
|
||||||
@change="maEvent.handleChangeEvent(props.component, $event)"
|
@change="rv('onChange', $event)"
|
||||||
@popup-visible-change="maEvent.customeEvent(props.component, $event, 'onPopupVisibleChange')"
|
@popup-visible-change="rv('onPopupVisibleChange', $event)"
|
||||||
@clear="maEvent.handleCommonEvent(props.component, 'onClear')"
|
@clear="rv('onClear')"
|
||||||
@search="maEvent.customeEvent(props.component, $event, 'onSearch')"
|
@search="rv('onSearch', $event)"
|
||||||
>
|
>
|
||||||
</a-tree-select>
|
</a-tree-select>
|
||||||
</slot>
|
</slot>
|
||||||
@@ -60,9 +55,9 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
import { handlerCascader } from "../js/networkRequest.js"
|
import { handlerCascader } from "../js/networkRequest.js"
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -71,12 +66,16 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
const dictList = inject("dictList")
|
const dictList = inject("dictList")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const dictIndex = index.match(/^(\w+\.)\d+\./)
|
const dictIndex = index.match(/^(\w+\.)\d+\./)
|
||||||
? index.match(/^(\w+\.)\d+\./)[1] + props.component.dataIndex
|
? index.match(/^(\w+\.)\d+\./)[1] + props.component.dataIndex
|
||||||
: props.component.dataIndex
|
: props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index) ?? "")
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => get(formModel.value, index),
|
() => get(formModel.value, index),
|
||||||
@@ -94,8 +93,6 @@ if (props.component.dict && (props.component.dict.name || props.component.dict.d
|
|||||||
value.value = value.value + ""
|
value.value = value.value + ""
|
||||||
}
|
}
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -41,16 +36,20 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaUpload from "@/components/ma-upload/index.vue"
|
import MaUpload from "@/components/ma-upload/index.vue"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -66,8 +65,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
@@ -27,16 +22,20 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaUserSelect from "@/components/ma-user/index.vue"
|
import MaUserSelect from "@/components/ma-user/index.vue"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -56,8 +55,6 @@ if (props.component.multiple && !value.value) {
|
|||||||
value.value = []
|
value.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
@@ -12,16 +16,20 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaUserInfo from "@/components/ma-userInfo/index.vue"
|
import MaUserInfo from "@/components/ma-userInfo/index.vue"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
customField: { type: String, default: undefined }
|
customField: { type: String, default: undefined }
|
||||||
})
|
})
|
||||||
|
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -37,8 +45,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ma-form-item
|
<ma-form-item
|
||||||
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
v-if="typeof props.component.display == 'undefined' || props.component.display === true"
|
||||||
@@ -23,10 +27,10 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, onMounted, watch } from "vue"
|
import { ref, inject, onMounted, watch } from "vue"
|
||||||
import { get, set } from "lodash"
|
import { get, set } from "lodash-es"
|
||||||
import MaVerifyCode from "@/components/ma-verifyCode/index.vue"
|
import MaVerifyCode from "@/components/ma-verifyCode/index.vue"
|
||||||
import MaFormItem from "./form-item.vue"
|
import MaFormItem from "./form-item.vue"
|
||||||
import { maEvent } from "../js/formItemMixin.js"
|
import { runEvent } from "../js/event.js"
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
component: Object,
|
component: Object,
|
||||||
@@ -35,6 +39,10 @@ const props = defineProps({
|
|||||||
|
|
||||||
const formVerifyCode = ref()
|
const formVerifyCode = ref()
|
||||||
const formModel = inject("formModel")
|
const formModel = inject("formModel")
|
||||||
|
const getColumnService = inject("getColumnService")
|
||||||
|
const columns = inject("columns")
|
||||||
|
const rv = async (ev, value = undefined) =>
|
||||||
|
await runEvent(props.component, ev, { formModel, getColumnService, columns }, value)
|
||||||
const index = props.customField ?? props.component.dataIndex
|
const index = props.customField ?? props.component.dataIndex
|
||||||
const value = ref(get(formModel.value, index))
|
const value = ref(get(formModel.value, index))
|
||||||
|
|
||||||
@@ -63,10 +71,8 @@ component.rules = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
maEvent.handleCommonEvent(props.component, "onCreated")
|
rv("onCreated")
|
||||||
onMounted(() => {
|
onMounted(() => rv("onMounted"))
|
||||||
maEvent.handleCommonEvent(props.component, "onMounted")
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<a-spin :loading="formLoading" :tip="options.loadingText" class="w-full">
|
<a-spin :loading="formLoading" :tip="options.loadingText" class="w-full ma-form-spin">
|
||||||
<div
|
<div
|
||||||
v-if="options.showFormTitle"
|
v-if="options.showFormTitle"
|
||||||
:class="['ma-form-title', options.formTitleClass]"
|
:class="['ma-form-title', options.formTitleClass]"
|
||||||
@@ -19,80 +23,76 @@
|
|||||||
:rules="options?.rules"
|
:rules="options?.rules"
|
||||||
@submit="formSubmit"
|
@submit="formSubmit"
|
||||||
>
|
>
|
||||||
<template v-for="(component, componentIndex) in columns" :key="componentIndex">
|
<slot name="formContent">
|
||||||
<component :is="getComponentName(component?.formType ?? 'input')" :component="component">
|
<template v-for="(component, componentIndex) in columns" :key="componentIndex">
|
||||||
<template v-for="slot in Object.keys($slots)" #[slot]="component">
|
<component
|
||||||
<slot :name="slot" v-bind="component" />
|
:is="getComponentName(component?.formType ?? 'input')"
|
||||||
</template>
|
:component="component"
|
||||||
</component>
|
:ref="setDialogRef"
|
||||||
</template>
|
>
|
||||||
<div class="text-center" v-if="options.showButtons">
|
<template v-for="slot in Object.keys($slots)" #[slot]="component">
|
||||||
<a-space>
|
<slot :name="slot" v-bind="component" />
|
||||||
<slot name="formBeforeButtons" />
|
</template>
|
||||||
<slot name="formButtons">
|
</component>
|
||||||
<a-button
|
</template>
|
||||||
:type="options.submitType"
|
<div class="text-center" v-if="options.showButtons">
|
||||||
:status="options.submitStatus"
|
<a-space>
|
||||||
v-if="options.submitShowBtn"
|
<slot name="formBeforeButtons" />
|
||||||
html-type="submit"
|
<slot name="formButtons">
|
||||||
>
|
<a-button
|
||||||
<template #icon v-if="options?.submitIcon">
|
:type="options.submitType"
|
||||||
<component :is="options.submitIcon" />
|
:status="options.submitStatus"
|
||||||
</template>
|
v-if="options.submitShowBtn"
|
||||||
{{ options.submitText }}
|
html-type="submit"
|
||||||
</a-button>
|
>
|
||||||
<a-button
|
<template #icon v-if="options?.submitIcon">
|
||||||
:type="options.resetType"
|
<component :is="options.submitIcon" />
|
||||||
:status="options.resetStatus"
|
</template>
|
||||||
v-if="options.resetShowBtn"
|
{{ options.submitText }}
|
||||||
@click="resetForm"
|
</a-button>
|
||||||
>
|
<a-button
|
||||||
<template #icon v-if="options?.resetIcon">
|
:type="options.resetType"
|
||||||
<component :is="options.resetIcon" />
|
:status="options.resetStatus"
|
||||||
</template>
|
v-if="options.resetShowBtn"
|
||||||
{{ options.resetText }}
|
@click="resetForm"
|
||||||
</a-button>
|
>
|
||||||
</slot>
|
<template #icon v-if="options?.resetIcon">
|
||||||
<slot name="formAfterButtons" />
|
<component :is="options.resetIcon" />
|
||||||
</a-space>
|
</template>
|
||||||
</div>
|
{{ options.resetText }}
|
||||||
|
</a-button>
|
||||||
|
</slot>
|
||||||
|
<slot name="formAfterButtons" />
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { isNil, get } from "lodash"
|
|
||||||
import { ref, watch, provide, onMounted, nextTick, getCurrentInstance } from "vue"
|
import { ref, watch, provide, onMounted, nextTick, getCurrentInstance } from "vue"
|
||||||
|
import { isNil, set, get, cloneDeep } from "lodash"
|
||||||
import defaultOptions from "./js/defaultOptions.js"
|
import defaultOptions from "./js/defaultOptions.js"
|
||||||
import { getComponentName, toHump, interactiveControl, handleFlatteningColumns } from "./js/utils.js"
|
import {
|
||||||
|
getComponentName,
|
||||||
|
toHump,
|
||||||
|
interactiveControl,
|
||||||
|
handleFlatteningColumns,
|
||||||
|
insertGlobalCssToHead,
|
||||||
|
insertGlobalFunctionsToHtml
|
||||||
|
} from "./js/utils.js"
|
||||||
import { loadDict, handlerCascader } from "./js/networkRequest.js"
|
import { loadDict, handlerCascader } from "./js/networkRequest.js"
|
||||||
import arrayComponentDefault from "./js/defaultArrayComponent.js"
|
import arrayComponentDefault from "./js/defaultArrayComponent.js"
|
||||||
|
import ColumnService from "./js/columnService.js"
|
||||||
|
|
||||||
import { maEvent } from "./js/formItemMixin.js"
|
import { runEvent } from "./js/event.js"
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
|
|
||||||
const containerList = import.meta.glob("./containerItem/*.vue", { eager: true })
|
|
||||||
const componentList = import.meta.glob("./formItem/*.vue", { eager: true })
|
|
||||||
const _this = getCurrentInstance().appContext
|
|
||||||
for (const path in containerList) {
|
|
||||||
const name = path.match(/([A-Za-z0-9_-]+)/g)[1]
|
|
||||||
const containerName = `Ma${toHump(name)}`
|
|
||||||
if (!_this.components[containerName]) {
|
|
||||||
_this.app.component(containerName, containerList[path].default)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const path in componentList) {
|
|
||||||
const name = path.match(/([A-Za-z0-9_-]+)/g)[1]
|
|
||||||
const componentName = `Ma${toHump(name)}`
|
|
||||||
if (!_this.components[componentName]) {
|
|
||||||
_this.app.component(componentName, componentList[path].default)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const formLoading = ref(false)
|
const formLoading = ref(false)
|
||||||
const maFormRef = ref()
|
const maFormRef = ref()
|
||||||
|
const dialogRefs = ref({})
|
||||||
const flatteningColumns = ref([])
|
const flatteningColumns = ref([])
|
||||||
const dictList = ref({})
|
const dictList = ref({})
|
||||||
const cascaderList = ref([])
|
const cascaderList = ref([])
|
||||||
@@ -103,7 +103,7 @@ const props = defineProps({
|
|||||||
columns: { type: Array },
|
columns: { type: Array },
|
||||||
options: { type: Object, default: {} }
|
options: { type: Object, default: {} }
|
||||||
})
|
})
|
||||||
const emit = defineEmits(["onSubmit", "update:modelValue"])
|
const emit = defineEmits(["submit", "update:modelValue"])
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
@@ -114,16 +114,38 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => form.value,
|
() => form.value,
|
||||||
(vl) => {
|
(vl) => {
|
||||||
interactiveControl(vl, flatteningColumns.value)
|
interactiveControl(vl, flatteningColumns.value, { getColumnService, dictList })
|
||||||
emit("update:modelValue", vl)
|
emit("update:modelValue", vl)
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
const options = ref(Object.assign(JSON.parse(JSON.stringify(defaultOptions)), props.options))
|
const options = ref({})
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
|
const containerList = import.meta.glob("./containerItem/*.vue", { eager: true })
|
||||||
|
const componentList = import.meta.glob("./formItem/*.vue", { eager: true })
|
||||||
|
const _this = getCurrentInstance()?.appContext ?? undefined
|
||||||
|
|
||||||
|
if (_this) {
|
||||||
|
for (const path in containerList) {
|
||||||
|
const name = path.match(/([A-Za-z0-9_-]+)/g)[1]
|
||||||
|
const containerName = `Ma${toHump(name)}`
|
||||||
|
if (!_this.components[containerName]) {
|
||||||
|
_this.app.component(containerName, containerList[path].default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const path in componentList) {
|
||||||
|
const name = path.match(/([A-Za-z0-9_-]+)/g)[1]
|
||||||
|
const componentName = `Ma${toHump(name)}`
|
||||||
|
if (!_this.components[componentName]) {
|
||||||
|
_this.app.component(componentName, componentList[path].default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
|
|
||||||
handleFlatteningColumns(props.columns, flatteningColumns.value)
|
handleFlatteningColumns(props.columns, flatteningColumns.value)
|
||||||
@@ -137,16 +159,29 @@ const init = async () => {
|
|||||||
|
|
||||||
// 初始化数据
|
// 初始化数据
|
||||||
flatteningColumns.value.map(async (item) => {
|
flatteningColumns.value.map(async (item) => {
|
||||||
if (isNil(form.value[item.dataIndex]) && !item.isChildrenForm) {
|
if (isNil(form.value[item.dataIndex])) {
|
||||||
form.value[item.dataIndex] = undefined
|
form.value[item.dataIndex] = undefined
|
||||||
if (arrayComponentDefault.includes(item.formType) && !item.isChildrenForm) {
|
if (arrayComponentDefault.includes(item.formType)) {
|
||||||
form.value[item.dataIndex] = []
|
form.value[item.dataIndex] = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理带点的字段
|
||||||
|
if (typeof item.dataIndex === "string") {
|
||||||
|
if (item.dataIndex.indexOf(".") > -1) {
|
||||||
|
const value = cloneDeep(form.value[item.dataIndex])
|
||||||
|
delete form.value[item.dataIndex]
|
||||||
|
set(form.value, item.dataIndex, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 字典
|
// 字典
|
||||||
if (!cascaderList.value.includes(item.dataIndex) && item.dict) {
|
if (!cascaderList.value.includes(item.dataIndex) && item.dict) {
|
||||||
await loadDict(dictList.value, item)
|
await loadDict(dictList.value, item, options.value.sourceList, {
|
||||||
|
formModel: form.value,
|
||||||
|
getColumnService,
|
||||||
|
columns: flatteningColumns.value
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 联动
|
// 联动
|
||||||
@@ -161,22 +196,31 @@ const init = async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
await nextTick(() => {
|
await nextTick(() => {
|
||||||
interactiveControl(form.value, flatteningColumns.value)
|
interactiveControl(form.value, flatteningColumns.value, { getColumnService, dictList })
|
||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
provide("options", options.value)
|
const setDialogRef = async (ref) => {
|
||||||
provide("columns", flatteningColumns)
|
await nextTick(() => {
|
||||||
provide("dictList", dictList)
|
if (ref?.getDataIndex) {
|
||||||
provide("formModel", form)
|
dialogRefs.value[ref.getDataIndex()] = ref
|
||||||
provide("formLoading", formLoading)
|
if (!form.value[ref.getDataIndex()]) {
|
||||||
maEvent.handleCommonEvent(options.value, "onCreated")
|
form.value[ref.getDataIndex()] = {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
// maEvent.handleCommonEvent(options.value, 'onCreated')
|
||||||
maEvent.handleCommonEvent(options.value, "onMounted")
|
|
||||||
options.value.init && init()
|
onMounted(async () => {
|
||||||
maEvent.handleCommonEvent(options.value, "onInit")
|
updateOptions()
|
||||||
|
insertGlobalCssToHead(options.value.globalCss)
|
||||||
|
insertGlobalFunctionsToHtml(options.value.globalFunction)
|
||||||
|
// maEvent.handleCommonEvent(options.value, 'onMounted')
|
||||||
|
options.value.init && (await init())
|
||||||
|
// maEvent.handleCommonEvent(options.value, 'onInit')
|
||||||
})
|
})
|
||||||
|
|
||||||
const done = (status) => (formLoading.value = status)
|
const done = (status) => (formLoading.value = status)
|
||||||
@@ -192,81 +236,56 @@ const validateForm = async () => {
|
|||||||
const resetForm = async () => await maFormRef.value.resetFields()
|
const resetForm = async () => await maFormRef.value.resetFields()
|
||||||
const clearValidate = async () => await maFormRef.value.clearValidate()
|
const clearValidate = async () => await maFormRef.value.clearValidate()
|
||||||
|
|
||||||
const formSubmit = async () => ((await validateForm()) && !formLoading.value) || emit("onSubmit", form.value, done)
|
const formSubmit = async () => {
|
||||||
|
if (await validateForm()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
emit("submit", form.value, done)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取column属性服务类
|
||||||
|
* @returns ColumnService
|
||||||
|
*/
|
||||||
|
const getColumnService = (strictMode = true) => {
|
||||||
|
return new ColumnService(
|
||||||
|
{
|
||||||
|
columns: flatteningColumns.value,
|
||||||
|
cascaders: cascaderList.value,
|
||||||
|
dicts: dictList.value,
|
||||||
|
refs: dialogRefs.value
|
||||||
|
},
|
||||||
|
strictMode
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const getFormRef = () => maFormRef.value
|
const getFormRef = () => maFormRef.value
|
||||||
const getDictList = () => dictList.value
|
const getDictList = () => dictList.value
|
||||||
const getDictService = () => {
|
|
||||||
const DictService = function (dictList) {
|
|
||||||
/**
|
|
||||||
* dict项服务类
|
|
||||||
* @param dataIndex
|
|
||||||
* @param dictData
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
const DictItemService = function (dataIndex, dictData) {
|
|
||||||
this.dict = dictData
|
|
||||||
this.dataIndex = dataIndex
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回原DictData对象
|
|
||||||
* @returns {*}
|
|
||||||
*/
|
|
||||||
this.getRawDictData = () => {
|
|
||||||
return this.dict
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 追加
|
|
||||||
* @param label
|
|
||||||
* @param value
|
|
||||||
* @param extend
|
|
||||||
*/
|
|
||||||
this.append = (label, value, extend = {}) => {
|
|
||||||
this.getRawDictData().push(
|
|
||||||
Object.assign(
|
|
||||||
{
|
|
||||||
label: label,
|
|
||||||
value: value
|
|
||||||
},
|
|
||||||
extend
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 重新加载dict
|
|
||||||
* @param dictConfig
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
this.loadDict = (dictConfig) => {
|
|
||||||
return loadDict(dictList, { formType: "select", dict: dictConfig, dataIndex: this.dataIndex })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dictMap = new Map()
|
|
||||||
for (const [dataIndex, dictData] of Object.entries(dictList)) {
|
|
||||||
this.dictMap.set(dataIndex, new DictItemService(dataIndex, dictData))
|
|
||||||
}
|
|
||||||
this.get = (key) => {
|
|
||||||
return this.dictMap.get(key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new DictService(getDictList())
|
|
||||||
}
|
|
||||||
const getColumns = () => flatteningColumns.value
|
const getColumns = () => flatteningColumns.value
|
||||||
const getCascaderList = () => cascaderList.value
|
const getCascaderList = () => cascaderList.value
|
||||||
const getFormData = () => form.value
|
const getFormData = () => form.value
|
||||||
|
const updateOptions = () => (options.value = Object.assign(cloneDeep(defaultOptions), props.options))
|
||||||
|
|
||||||
|
provide("options", options.value)
|
||||||
|
provide("columns", flatteningColumns)
|
||||||
|
provide("dictList", dictList)
|
||||||
|
provide("formModel", form)
|
||||||
|
provide("formLoading", formLoading)
|
||||||
|
provide("getColumnService", getColumnService)
|
||||||
|
provide("maFormRef", maFormRef)
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
init,
|
init,
|
||||||
getFormRef,
|
getFormRef,
|
||||||
getColumns,
|
getColumns,
|
||||||
getDictList,
|
getDictList,
|
||||||
getDictService,
|
getColumnService,
|
||||||
getCascaderList,
|
getCascaderList,
|
||||||
getFormData,
|
getFormData,
|
||||||
validateForm,
|
validateForm,
|
||||||
resetForm,
|
resetForm,
|
||||||
clearValidate
|
clearValidate,
|
||||||
|
updateOptions
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
175
cdTMP/src/components/ma-form/js/columnService.js
Normal file
175
cdTMP/src/components/ma-form/js/columnService.js
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
import { loadDict } from "@cps/ma-form/js/networkRequest"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* columnService 列服务处理类
|
||||||
|
* 首先感谢 @NEKGod 提交的PR,此功能原本写在了 Ma-Crud 组件,我特意摘出来,封装成类通过引用来调用
|
||||||
|
* @author NEKGod, X.Mo <root@imoi.cn>
|
||||||
|
*/
|
||||||
|
|
||||||
|
const objectService = function (item) {
|
||||||
|
this.setAttr = (key, value) => {
|
||||||
|
item[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getAttr = (key) => {
|
||||||
|
return item[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
this.get = () => {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set = (config = {}) => {
|
||||||
|
for (let [key, value] of Object.entries(config)) {
|
||||||
|
item[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dict项服务类
|
||||||
|
* @param dataIndex
|
||||||
|
* @param dictData
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
const dictService = function (dataIndex, dictData, dicts, columns) {
|
||||||
|
this.columns = columns
|
||||||
|
this.dicts = dicts
|
||||||
|
this.dictData = dictData
|
||||||
|
this.dataIndex = dataIndex
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回原DictData对象
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
this.getRawDictData = () => {
|
||||||
|
return this.dictData
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 追加
|
||||||
|
* @param label
|
||||||
|
* @param value
|
||||||
|
* @param extend
|
||||||
|
*/
|
||||||
|
this.append = (label, value, extend = {}) => {
|
||||||
|
this.getRawDictData().push(
|
||||||
|
Object.assign(
|
||||||
|
{
|
||||||
|
label: label,
|
||||||
|
value: value
|
||||||
|
},
|
||||||
|
extend
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 重新加载dict
|
||||||
|
* @param dictConfig
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
this.loadDict = async (dictConfig) => {
|
||||||
|
this.columns.setAttr("dict", dictConfig)
|
||||||
|
await loadDict(this.dicts, { formType: "select", dict: dictConfig, dataIndex: this.dataIndex })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ColumnService {
|
||||||
|
/**
|
||||||
|
* @type {Map<string, Object>}
|
||||||
|
*/
|
||||||
|
columnMap = new Map()
|
||||||
|
|
||||||
|
dictMap = new Map()
|
||||||
|
|
||||||
|
columns
|
||||||
|
|
||||||
|
cascaders
|
||||||
|
|
||||||
|
dicts
|
||||||
|
|
||||||
|
refs
|
||||||
|
|
||||||
|
strictMode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param data
|
||||||
|
* @param strictMode
|
||||||
|
*/
|
||||||
|
constructor(data, strictMode) {
|
||||||
|
this.columns = data.columns
|
||||||
|
this.cascaders = data.cascaders
|
||||||
|
this.dicts = data.dicts
|
||||||
|
this.refs = data?.refs ?? {}
|
||||||
|
this.strictMode = strictMode
|
||||||
|
|
||||||
|
this.columns.forEach((item) => {
|
||||||
|
this.columnMap.set(item.dataIndex, new objectService(item))
|
||||||
|
})
|
||||||
|
|
||||||
|
for (const [dataIndex, dictData] of Object.entries(this.dicts)) {
|
||||||
|
this.dictMap.set(dataIndex, new dictService(dataIndex, dictData, this.dicts, this.columnMap.get(dataIndex)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getDialogRefs(refName = undefined) {
|
||||||
|
return refName ? this.refs[refName] : this.refs
|
||||||
|
}
|
||||||
|
|
||||||
|
getDictService(dataIndex) {
|
||||||
|
return this.dictMap.get(dataIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
get(dataIndex) {
|
||||||
|
return this.columnMap.get(dataIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmpty(dataIndex) {
|
||||||
|
return !this.columnMap.has(dataIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
exist(dataIndex) {
|
||||||
|
return !this.isEmpty(dataIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
async append(item, appendStartDataIndex = null) {
|
||||||
|
if (this.strictMode === true && item.dataIndex && this.exist(item.dataIndex)) {
|
||||||
|
console.warn(
|
||||||
|
`严格模式:columnService.append(item) 参数中未有item.dataIndex属性或者item.dataIndex已存在column.${item.dataIndex}`
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (this.cascaders.includes(item.dataIndex) && item.dict) {
|
||||||
|
await loadDict(this.dicts, item)
|
||||||
|
}
|
||||||
|
this.columns.push(item)
|
||||||
|
this.columnMap.set(item.dataIndex, new objectService(item))
|
||||||
|
// 获取排序
|
||||||
|
if (appendStartDataIndex !== null) {
|
||||||
|
let appendIndex =
|
||||||
|
this.columns
|
||||||
|
.map((item) => {
|
||||||
|
return item.dataIndex
|
||||||
|
})
|
||||||
|
?.indexOf(appendStartDataIndex) ?? -1
|
||||||
|
if (appendIndex === -1) {
|
||||||
|
return this.append(item, null)
|
||||||
|
}
|
||||||
|
let sortIndex = 0
|
||||||
|
let appendPosIndex = 0
|
||||||
|
this.columns.forEach((sortItem) => {
|
||||||
|
if (sortItem.dataIndex === appendStartDataIndex) {
|
||||||
|
appendPosIndex = sortIndex
|
||||||
|
} else if (sortItem.dataIndex === item.dataIndex) {
|
||||||
|
sortIndex = appendPosIndex + 1
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
sortItem.sortIndex = sortIndex
|
||||||
|
sortIndex += 2
|
||||||
|
})
|
||||||
|
this.columns.sort((a, b) => a.sortIndex - b.sortIndex)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ColumnService
|
||||||
@@ -47,5 +47,13 @@ export default {
|
|||||||
// 自定义标题样式css
|
// 自定义标题样式css
|
||||||
formTitleStyle: "",
|
formTitleStyle: "",
|
||||||
// 自定义标题样式class
|
// 自定义标题样式class
|
||||||
formTitleClass: []
|
formTitleClass: [],
|
||||||
|
|
||||||
|
// 数据源列表,配合表单设计器使用,单独无法使用
|
||||||
|
sourceList: [],
|
||||||
|
|
||||||
|
// 全局CSS class
|
||||||
|
globalCss: "",
|
||||||
|
// 全局function
|
||||||
|
globalFunction: ""
|
||||||
}
|
}
|
||||||
|
|||||||
39
cdTMP/src/components/ma-form/js/event.js
Normal file
39
cdTMP/src/components/ma-form/js/event.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { isString, isFunction } from "lodash-es"
|
||||||
|
|
||||||
|
export const haveArgsEvent = async (component, value, evName, maformObj) => {
|
||||||
|
if (component[evName]) {
|
||||||
|
if (isFunction(component[evName])) {
|
||||||
|
return await component[evName](value, maformObj)
|
||||||
|
}
|
||||||
|
if (isString(component[evName])) {
|
||||||
|
const customFn = new Function("value", "maFormObject", component[evName])
|
||||||
|
return await customFn.call(component, value, maformObj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const notHaveArgsEvent = async (component, evName, maformObj) => {
|
||||||
|
if (component[evName]) {
|
||||||
|
if (isFunction(component[evName])) {
|
||||||
|
return await component[evName](maformObj)
|
||||||
|
}
|
||||||
|
if (isString(component[evName])) {
|
||||||
|
const customFn = new Function("maFormObject", component[evName])
|
||||||
|
return await customFn.call(component[evName], maformObj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const tabAddEvent = (component, maformObj) => {
|
||||||
|
haveArgsEvent(component, component?.tabs, "onTabAdd", maformObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const tabDeleteEvent = (component, value, maformObj) => {
|
||||||
|
haveArgsEvent(component, { tabs: component?.tabs, value }, "onTabDelete", maformObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const runEvent = async (component, evName, maformObj, value = undefined) => {
|
||||||
|
return value
|
||||||
|
? await haveArgsEvent(component, value, evName, maformObj)
|
||||||
|
: await notHaveArgsEvent(component, evName, maformObj)
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { isString, isFunction } from "lodash"
|
import { isString, isFunction } from "lodash-es"
|
||||||
export const maEvent = {
|
export const maEvent = {
|
||||||
customeEvent: async (component, value, evName) => {
|
customeEvent: async (component, value, evName) => {
|
||||||
if (component[evName]) {
|
if (component[evName]) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { isArray, isFunction, set } from "lodash"
|
import { toRaw } from "vue"
|
||||||
|
import { isArray, isFunction, set, isUndefined } from "lodash-es"
|
||||||
import { request } from "@/utils/request"
|
import { request } from "@/utils/request"
|
||||||
import commonApi from "@/api/common"
|
import commonApi from "@/api/common"
|
||||||
|
import { Message } from "@arco-design/web-vue"
|
||||||
import tool from "@/utils/tool"
|
import tool from "@/utils/tool"
|
||||||
|
|
||||||
export const allowUseDictComponent = [
|
export const allowUseDictComponent = [
|
||||||
@@ -14,8 +16,49 @@ export const allowUseDictComponent = [
|
|||||||
]
|
]
|
||||||
export const allowCoverComponent = ["radio", "checkbox", "select", "transfer", "cascader"]
|
export const allowCoverComponent = ["radio", "checkbox", "select", "transfer", "cascader"]
|
||||||
|
|
||||||
export const requestDict = (url, method, params, data, timeout = 10 * 1000) =>
|
export const coverSourceArrayToObj = (arr) => {
|
||||||
request({ url, method, params, data, timeout })
|
if (arr === null || arr.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
let obj = {}
|
||||||
|
const checkDataType = (type, value) => {
|
||||||
|
if (type === "string") {
|
||||||
|
return value.toString()
|
||||||
|
}
|
||||||
|
if (type === "number") {
|
||||||
|
return parseInt(value)
|
||||||
|
}
|
||||||
|
if (type === "bool") {
|
||||||
|
return value !== "false" && value !== 0 && (value === "true" || value) ? true : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arr.map((item) => (obj[item.name] = checkDataType(item.type, item.value)))
|
||||||
|
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
export const requestDict = (url, method, params, data, header = {}, timeout = 10 * 1000) => {
|
||||||
|
return request({ url, method, params, data, header, timeout })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const requestDataSource = async (config, maFormObject = {}) => {
|
||||||
|
try {
|
||||||
|
const response = await requestDict(
|
||||||
|
config.url,
|
||||||
|
config.type,
|
||||||
|
coverSourceArrayToObj(config.params),
|
||||||
|
coverSourceArrayToObj(config.data),
|
||||||
|
coverSourceArrayToObj(config.header),
|
||||||
|
config.timeout * 1000
|
||||||
|
)
|
||||||
|
const func = new Function("response", "config", "maFormObject", toRaw(config.response).getValue())
|
||||||
|
return await func.call(null, response, config, maFormObject)
|
||||||
|
} catch (err) {
|
||||||
|
const func = new Function("message", "response", "config", toRaw(config.errorHandle).getValue())
|
||||||
|
await func.call(null, Message, err, config)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const handlerDictProps = (item, tmpArr) => {
|
export const handlerDictProps = (item, tmpArr) => {
|
||||||
let data = []
|
let data = []
|
||||||
@@ -23,7 +66,7 @@ export const handlerDictProps = (item, tmpArr) => {
|
|||||||
let colors = {}
|
let colors = {}
|
||||||
let labelName = "label"
|
let labelName = "label"
|
||||||
let valueName = "value"
|
let valueName = "value"
|
||||||
if (item.dict.name && (!item.dict.url || !item.dict.data)) {
|
if (item?.dict?.name && (!item.dict.url || !item.dict.data)) {
|
||||||
labelName = "title"
|
labelName = "title"
|
||||||
valueName = "key"
|
valueName = "key"
|
||||||
}
|
}
|
||||||
@@ -37,10 +80,10 @@ export const handlerDictProps = (item, tmpArr) => {
|
|||||||
typeof dicItem["indeterminate"] == "undefined"
|
typeof dicItem["indeterminate"] == "undefined"
|
||||||
? false
|
? false
|
||||||
: dicItem["indeterminate"] === true
|
: dicItem["indeterminate"] === true
|
||||||
? true
|
? true
|
||||||
: false
|
: false
|
||||||
let value
|
let value
|
||||||
if (item.dict.name || item.dict.data) value = tmp.toString()
|
if (item.dict.name || item.dict.data) value = tmp?.toString() ?? tmp
|
||||||
else if (tmp === "true") value = true
|
else if (tmp === "true") value = true
|
||||||
else if (tmp === "false") value = false
|
else if (tmp === "false") value = false
|
||||||
else value = tmp
|
else value = tmp
|
||||||
@@ -56,61 +99,122 @@ export const handlerDictProps = (item, tmpArr) => {
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loadDict = async (dictList, item) => {
|
export const loadDict = async (dictList, item, sourceList = [], maFormObject = {}) => {
|
||||||
if (allowUseDictComponent.includes(item.formType) && item.dict) {
|
if (!allowUseDictComponent.includes(item.formType)) {
|
||||||
if (item.dict.name) {
|
return
|
||||||
const response = await commonApi.getDict(item.dict.name)
|
}
|
||||||
if (response.data) {
|
const dataIndex = item.parentDataIndex ? `${item.parentDataIndex}.${item.dataIndex}` : item.dataIndex
|
||||||
dictList[item.dataIndex] = handlerDictProps(item, response.data)
|
if (item.dict.name) {
|
||||||
}
|
const response = await commonApi.getDict(item.dict.name)
|
||||||
} else if (item.dict.url) {
|
if (response.data) {
|
||||||
const dictData = tool.local.get("dictData")
|
dictList[dataIndex] = handlerDictProps(item, response.data)
|
||||||
if (item.dict.cache && dictData[item.dataIndex]) {
|
}
|
||||||
dictList[item.dataIndex] = dictData[item.dataIndex]
|
} else if (item.dict.remote) {
|
||||||
|
let requestData = {
|
||||||
|
openPage: item.dict?.openPage ?? false,
|
||||||
|
remoteOption: item.dict.remoteOption ?? {}
|
||||||
|
}
|
||||||
|
requestData = Object.assign(requestData, item.dict.pageOption)
|
||||||
|
|
||||||
|
if (requestData.openPage) {
|
||||||
|
const { data } = await requestDict(item.dict.remote, "POST", {}, requestData)
|
||||||
|
dictList[dataIndex] = handlerDictProps(item, data.items)
|
||||||
|
dictList[dataIndex].pageInfo = data.pageInfo
|
||||||
|
} else {
|
||||||
|
const dictData = tool.local.get("dictData") ?? {}
|
||||||
|
if (item.dict.cache && dictData[dataIndex]) {
|
||||||
|
dictList[dataIndex] = handlerDictProps(item, dictData[dataIndex])
|
||||||
} else {
|
} else {
|
||||||
const response = await requestDict(
|
const { data } = await requestDict(item.dict.remote, "POST", {}, requestData)
|
||||||
|
dictList[dataIndex] = handlerDictProps(item, data)
|
||||||
|
if (item.dict.cache) {
|
||||||
|
dictData[dataIndex] = data
|
||||||
|
tool.local.set("dictData", dictData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (item.dict.url) {
|
||||||
|
let requestData = {
|
||||||
|
openPage: item.dict?.openPage ?? false,
|
||||||
|
remoteOption: item.dict.remoteOption ?? {}
|
||||||
|
}
|
||||||
|
requestData = Object.assign(requestData, item.dict.pageOption)
|
||||||
|
|
||||||
|
if (requestData.openPage) {
|
||||||
|
if (item.dict?.method === "GET" || item.dict?.method === "get") {
|
||||||
|
item.dict.params = Object.assign(item.dict.params ?? {}, requestData)
|
||||||
|
} else {
|
||||||
|
item.dict.body = Object.assign(item.dict.body ?? {}, requestData)
|
||||||
|
}
|
||||||
|
const { data } = await requestDict(
|
||||||
|
item.dict.url,
|
||||||
|
item.dict.method || "GET",
|
||||||
|
item.dict.params || {},
|
||||||
|
item.dict.body || {}
|
||||||
|
)
|
||||||
|
dictList[dataIndex] = handlerDictProps(item, data.items)
|
||||||
|
dictList[dataIndex].pageInfo = data.pageInfo
|
||||||
|
} else {
|
||||||
|
const dictData = tool.local.get("dictData") ?? {}
|
||||||
|
if (item.dict.cache && dictData[dataIndex]) {
|
||||||
|
dictList[dataIndex] = handlerDictProps(item, dictData[dataIndex])
|
||||||
|
} else {
|
||||||
|
const { data } = await requestDict(
|
||||||
item.dict.url,
|
item.dict.url,
|
||||||
item.dict.method || "GET",
|
item.dict.method || "GET",
|
||||||
item.dict.params || {},
|
item.dict.params || {},
|
||||||
item.dict.body || {}
|
item.dict.body || {}
|
||||||
)
|
)
|
||||||
if (response.data) {
|
dictList[dataIndex] = handlerDictProps(item, data)
|
||||||
dictList[item.dataIndex] = handlerDictProps(item, response.data)
|
if (item.dict.cache) {
|
||||||
if (item.dict.cache) {
|
dictData[dataIndex] = data
|
||||||
dictData[item.dataIndex] = dictList[item.dataIndex]
|
tool.local.set("dictData", dictData)
|
||||||
tool.local.set("dictData", dictData)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (item.dict.data) {
|
}
|
||||||
if (isArray(item.dict.data)) {
|
} else if ((item?.sourceIndex || item?.sourceIndex === 0) && !isUndefined(sourceList[item?.sourceIndex])) {
|
||||||
dictList[item.dataIndex] = handlerDictProps(item, item.dict.data)
|
const config = sourceList[item.sourceIndex]
|
||||||
} else if (isFunction(item.dict.data)) {
|
const data = await requestDataSource(config, maFormObject)
|
||||||
const response = await item.dict.data()
|
dictList[dataIndex] = handlerDictProps(item, data)
|
||||||
dictList[item.dataIndex] = handlerDictProps(item, response)
|
} else if (item.dict.data) {
|
||||||
}
|
if (isArray(item.dict.data)) {
|
||||||
|
dictList[dataIndex] = handlerDictProps(item, item.dict.data)
|
||||||
|
} else if (isFunction(item.dict.data)) {
|
||||||
|
const response = await item.dict.data()
|
||||||
|
dictList[dataIndex] = handlerDictProps(item, response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestCascaderData = async (val, dict, dictList, name) => {
|
const requestCascaderData = async (val, dict, dictList, name) => {
|
||||||
if (dict && dict.url) {
|
if (dict && (dict.remote || dict.url)) {
|
||||||
|
let requestData = { openPage: dict?.openPage ?? false, remoteOption: dict.remoteOption ?? {} }
|
||||||
let response
|
let response
|
||||||
if (dict && dict.url.indexOf("{{key}}") > 0) {
|
const pageOption = Object.assign(requestData, dict.pageOption)
|
||||||
|
let url = dict.remote ?? dict.url
|
||||||
|
if (dict && url.indexOf("{{key}}") > 0) {
|
||||||
|
url = url.replace("{{key}}", val)
|
||||||
|
// 解析参数
|
||||||
|
let queryParams = tool.getRequestParams(url)
|
||||||
|
let urlIndex = url.indexOf("?")
|
||||||
|
if (urlIndex !== -1) {
|
||||||
|
url = url.substring(0, urlIndex)
|
||||||
|
}
|
||||||
response = await requestDict(
|
response = await requestDict(
|
||||||
dict.url.replace("{{key}}", val),
|
url,
|
||||||
dict.method || "GET",
|
dict.method ?? "GET",
|
||||||
dict.params || {},
|
Object.assign(dict.params || {}, requestData.openPage ? pageOption : {}, queryParams),
|
||||||
dict.data || {}
|
Object.assign(dict.data || {}, requestData.openPage ? pageOption : {})
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let temp = { key: val }
|
let temp = Object.assign({ key: val }, requestData.openPage ? pageOption : {})
|
||||||
const params = Object.assign(dict.params || {}, temp)
|
const params = Object.assign(dict.params || {}, temp)
|
||||||
const data = Object.assign(dict.data || {}, temp)
|
const data = Object.assign(dict.data || {}, temp)
|
||||||
response = await requestDict(dict.url, dict.method || "GET", params || {}, data || {})
|
response = await requestDict(url, dict.method ?? "GET", params || {}, data || {})
|
||||||
}
|
}
|
||||||
if (response.data && response.code === 200) {
|
if (response.data && response.code === 200) {
|
||||||
dictList[name] = response.data.map((dicItem) => {
|
let dataIems = requestData.openPage ? response.data.items : response.data
|
||||||
|
dictList[name] = dataIems.map((dicItem) => {
|
||||||
return {
|
return {
|
||||||
label: dicItem[(dict.props && dict.props.label) || "label"],
|
label: dicItem[(dict.props && dict.props.label) || "label"],
|
||||||
value: dicItem[(dict.props && dict.props.value) || "value"],
|
value: dicItem[(dict.props && dict.props.value) || "value"],
|
||||||
@@ -120,10 +224,11 @@ const requestCascaderData = async (val, dict, dictList, name) => {
|
|||||||
typeof dicItem["indeterminate"] == "undefined"
|
typeof dicItem["indeterminate"] == "undefined"
|
||||||
? false
|
? false
|
||||||
: dicItem["indeterminate"] === true
|
: dicItem["indeterminate"] === true
|
||||||
? true
|
? true
|
||||||
: false
|
: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
dictList[name].pageInfo = response.data.pageInfo ?? undefined
|
||||||
} else {
|
} else {
|
||||||
console.error(response)
|
console.error(response)
|
||||||
}
|
}
|
||||||
@@ -133,9 +238,12 @@ const requestCascaderData = async (val, dict, dictList, name) => {
|
|||||||
export const handlerCascader = async (val, column, columns, dictList, formModel, clearData = true) => {
|
export const handlerCascader = async (val, column, columns, dictList, formModel, clearData = true) => {
|
||||||
if (column.cascaderItem && isArray(column.cascaderItem)) {
|
if (column.cascaderItem && isArray(column.cascaderItem)) {
|
||||||
column.cascaderItem.map(async (name) => {
|
column.cascaderItem.map(async (name) => {
|
||||||
const dict = columns.find((col) => col.dataIndex === name && col.dict).dict
|
const columnItem = columns.find((col) => col.dataIndex === name && col.dict)
|
||||||
clearData && set(formModel, name, undefined)
|
const dataIndex = columnItem.parentDataIndex
|
||||||
requestCascaderData(val, dict, dictList, name)
|
? `${columnItem.parentDataIndex}.${columnItem.dataIndex}`
|
||||||
|
: columnItem.dataIndex
|
||||||
|
clearData && set(formModel, dataIndex, undefined)
|
||||||
|
await requestCascaderData(val, columnItem.dict, dictList, dataIndex)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,30 @@
|
|||||||
import { isEmpty, isFunction, get, set } from "lodash"
|
import { isEmpty, isFunction, get, set } from "lodash-es"
|
||||||
|
|
||||||
export const containerItems = ["tabs", "table", "card", "grid", "grid-tailwind", "children-form"]
|
export const containerItems = ["tabs", "table", "card", "grid", "grid-tailwind", "children-form"]
|
||||||
export const inputType = ["input", "input-password", "input-search"]
|
export const inputType = ["input", "input-password", "input-search"]
|
||||||
export const pickerType = ["date", "month", "year", "week", "quarter", "range", "time"]
|
export const pickerType = ["date", "month", "year", "week", "quarter", "range", "time"]
|
||||||
|
|
||||||
export const interactiveControl = (form, columns) => {
|
export const interactiveControl = (form, columns, maFormObject) => {
|
||||||
const obj = []
|
const obj = []
|
||||||
|
const names = []
|
||||||
|
const keys = Object.keys(form)
|
||||||
|
if (keys && keys.length > 0) {
|
||||||
|
keys.map((item) => {
|
||||||
|
if (form[item] && typeof form[item] === "object") {
|
||||||
|
for (let name in form[item]) {
|
||||||
|
names.push(`${item}.${name}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
for (let name in form) {
|
for (let name in form) {
|
||||||
columns.map((item) => {
|
columns.map((item) => {
|
||||||
if (item.dataIndex === name && item.control && isFunction(item.control)) {
|
if (
|
||||||
obj.push(item.control(get(form, name), form))
|
(item.dataIndex === name || names.includes(item.dataIndex)) &&
|
||||||
|
item.onControl &&
|
||||||
|
isFunction(item.onControl)
|
||||||
|
) {
|
||||||
|
obj.push(item.onControl(get(form, item.dataIndex), maFormObject))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -56,7 +71,7 @@ export const getComponentName = (formType) => {
|
|||||||
return `MaForm${toHump(formType)}`
|
return `MaForm${toHump(formType)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export const handleFlatteningColumns = (data, columns, isChildrenForm = undefined) => {
|
export const handleFlatteningColumns = (data, columns) => {
|
||||||
for (let key in data) {
|
for (let key in data) {
|
||||||
const item = data[key]
|
const item = data[key]
|
||||||
if (containerItems.includes(item.formType)) {
|
if (containerItems.includes(item.formType)) {
|
||||||
@@ -90,15 +105,42 @@ export const handleFlatteningColumns = (data, columns, isChildrenForm = undefine
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
// case 'children-form':
|
case "children-form":
|
||||||
// item.formList && handleFlatteningColumns(item.formList, columns, item.dataIndex, true)
|
item.formList.map((list) => (list.parentDataIndex = item.dataIndex))
|
||||||
// break
|
item.formList && handleFlatteningColumns(item.formList, columns)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if (isChildrenForm) {
|
|
||||||
// item['isChildrenForm'] = true
|
|
||||||
// }
|
|
||||||
columns.push(item)
|
columns.push(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const insertGlobalCssToHead = (cssCode) => {
|
||||||
|
const head = document.getElementsByTagName("head")[0]
|
||||||
|
const oldStyle = document.getElementById("mineadmin-global-css")
|
||||||
|
oldStyle && head.removeChild(oldStyle)
|
||||||
|
|
||||||
|
const newStyle = document.createElement("style")
|
||||||
|
newStyle.rel = "stylesheet"
|
||||||
|
newStyle.id = "mineadmin-global-css"
|
||||||
|
try {
|
||||||
|
newStyle.appendChild(document.createTextNode(cssCode))
|
||||||
|
} catch (ex) {
|
||||||
|
newStyle.styleSheet.cssText = cssCode
|
||||||
|
}
|
||||||
|
|
||||||
|
head.appendChild(newStyle)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const insertGlobalFunctionsToHtml = (functionsCode) => {
|
||||||
|
const bodyEle = document.getElementsByTagName("body")[0]
|
||||||
|
const oldScriptEle = document.getElementById("mineadmin-global-functions")
|
||||||
|
oldScriptEle && bodyEle.removeChild(oldScriptEle)
|
||||||
|
|
||||||
|
const newScriptEle = document.createElement("script")
|
||||||
|
newScriptEle.id = "mineadmin-global-functions"
|
||||||
|
newScriptEle.type = "text/javascript"
|
||||||
|
newScriptEle.innerHTML = functionsCode
|
||||||
|
bodyEle.appendChild(newScriptEle)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,126 +1,128 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<a-input-group class="w-full">
|
<a-input-group class="w-full">
|
||||||
<a-input placeholder="请点击右侧按钮选择图标" allow-clear v-model="currentIcon" />
|
<a-input placeholder="请点击右侧按钮选择图标" v-if="props.preview" allow-clear v-model="currentIcon" />
|
||||||
<div class="icon-container" v-if="props.preview">
|
<div class="icon-container" v-if="props.preview">
|
||||||
<component :is="currentIcon" v-if="currentIcon" />
|
<component :is="currentIcon" v-if="currentIcon" />
|
||||||
</div>
|
</div>
|
||||||
<a-button type="primary" @click="() => (visible = true)">选择图标</a-button>
|
<a-button type="primary" @click="() => visible = true">选择图标</a-button>
|
||||||
</a-input-group>
|
</a-input-group>
|
||||||
|
|
||||||
<a-modal v-model:visible="visible" width="800px" draggable :footer="false">
|
<a-modal v-model:visible="visible" width="800px" draggable :footer="false">
|
||||||
<template #title>选择图标</template>
|
<template #title>选择图标</template>
|
||||||
<a-tabs class="tabs">
|
<a-tabs class="tabs">
|
||||||
<a-tab-pane key="arco" title="Arco Design">
|
<a-tab-pane key="arco" title="Arco Design">
|
||||||
<ul class="arco">
|
<ul class="arco">
|
||||||
<li v-for="icon in arcodesignIcons" :key="icon" @click="selectIcon(icon, 'arco')">
|
<li
|
||||||
<component :is="icon" />
|
v-for="icon in arcodesignIcons"
|
||||||
</li>
|
:key="icon"
|
||||||
</ul>
|
@click="selectIcon(icon, 'arco')"
|
||||||
</a-tab-pane>
|
>
|
||||||
<a-tab-pane key="mine" title="MineAdmin">
|
<component :is="icon" />
|
||||||
<ul class="mine">
|
</li>
|
||||||
<li v-for="icon in mineadminIcons" :key="icon" @click="selectIcon(icon, 'mine')">
|
</ul>
|
||||||
<component :is="icon" />
|
</a-tab-pane>
|
||||||
</li>
|
<a-tab-pane key="mine" title="MineAdmin">
|
||||||
</ul>
|
<ul class="mine">
|
||||||
</a-tab-pane>
|
<li
|
||||||
</a-tabs>
|
v-for="icon in mineadminIcons"
|
||||||
</a-modal>
|
:key="icon"
|
||||||
</div>
|
@click="selectIcon(icon, 'mine')"
|
||||||
|
>
|
||||||
|
<component :is="icon" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
</a-modal>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, ref, onMounted } from "vue"
|
import { reactive, ref, computed } from 'vue'
|
||||||
import * as arcoIcons from "@arco-design/web-vue/es/icon"
|
import * as arcoIcons from '@arco-design/web-vue/es/icon'
|
||||||
|
|
||||||
const mineadminIcons = reactive([])
|
const mineadminIcons = reactive([])
|
||||||
const arcodesignIcons = reactive([])
|
const arcodesignIcons = reactive([])
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const currentIcon = ref()
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: { type: String },
|
modelValue: { type: String },
|
||||||
preview: { type: Boolean, default: true }
|
preview: { type: Boolean, default: true },
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(["update:modelValue"])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
onMounted(() => (currentIcon.value = props.modelValue))
|
const currentIcon = computed({
|
||||||
|
get() {
|
||||||
|
return props.modelValue;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
// html标签名不能以数字开头
|
||||||
|
if ((/^[^\d].*/.test(value) && value) || !value) {
|
||||||
|
emit('update:modelValue', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
for (let icon in arcoIcons) {
|
for (let icon in arcoIcons) {
|
||||||
arcodesignIcons.push(icon)
|
arcodesignIcons.push(icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
arcodesignIcons.pop()
|
arcodesignIcons.pop()
|
||||||
|
|
||||||
const modules = import.meta.globEager("../../assets/ma-icons/*.vue")
|
const modules = import.meta.glob('../../assets/ma-icons/*.vue')
|
||||||
for (const path in modules) {
|
for (const path in modules) {
|
||||||
const name = path.match(/([A-Za-z0-9_-]+)/g)[2]
|
const name = path.match(/([A-Za-z0-9_-]+)/g)[2]
|
||||||
mineadminIcons.push(`MaIcon${name}`)
|
mineadminIcons.push(`MaIcon${name}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectIcon = (icon, className) => {
|
const selectIcon = (icon, className) => {
|
||||||
currentIcon.value = icon
|
currentIcon.value = icon
|
||||||
emit("update:modelValue", currentIcon.value)
|
|
||||||
visible.value = false
|
visible.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlerChange = (value) => {
|
const handlerChange = (value) => {
|
||||||
selectIcon(value, "")
|
selectIcon(value, '')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.icon-container {
|
.icon-container {
|
||||||
width: 50px;
|
width: 50px; height: 32px;
|
||||||
height: 32px;
|
background-color: var(--color-fill-1);
|
||||||
background-color: var(--color-fill-1);
|
display: flex; justify-content: center;
|
||||||
display: flex;
|
align-items: center;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
width: 1em;
|
width: 1em; fill: var(--color-text-1);
|
||||||
fill: var(--color-text-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs {
|
.tabs {
|
||||||
ul {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
padding-left: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
ul {
|
||||||
border: 2px solid var(--color-fill-4);
|
display: flex; flex-wrap: wrap; padding-left: 7px;
|
||||||
margin-bottom: 10px;
|
}
|
||||||
margin-right: 6px;
|
|
||||||
padding: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
li:hover,
|
li {
|
||||||
li.active {
|
border: 2px solid var(--color-fill-4); margin-bottom: 10px;
|
||||||
border: 2px solid rgb(var(--primary-6));
|
margin-right: 6px; padding: 5px; cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
& li svg {
|
li:hover, li.active {
|
||||||
width: 2.4em;
|
border: 2px solid rgb(var(--primary-6));
|
||||||
height: 2.4em;
|
}
|
||||||
}
|
|
||||||
|
& li svg {
|
||||||
|
width: 2.4em; height: 2.4em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
:deep(.arco-select-option-content) {
|
:deep(.arco-select-option-content) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,131 +1,150 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-modal
|
<a-modal
|
||||||
:width="prop.width"
|
:width="prop.width"
|
||||||
v-model:visible="modal.visible"
|
:fullscreen="isFull"
|
||||||
:on-before-ok="modal.submit"
|
v-model:visible="modal.visible"
|
||||||
:unmount-on-close="true"
|
:on-before-ok="modal.submit"
|
||||||
@cancel="modal.cancel"
|
:unmount-on-close="true"
|
||||||
|
@cancel="modal.cancel"
|
||||||
|
>
|
||||||
|
<template #title>
|
||||||
|
{{ prop.title }}
|
||||||
|
</template>
|
||||||
|
<slot></slot>
|
||||||
|
<slot name="body"></slot>
|
||||||
|
<a-card
|
||||||
|
class="mt-2"
|
||||||
|
:hoverable="true"
|
||||||
|
v-for="info in layout"
|
||||||
>
|
>
|
||||||
<template #title>
|
<ma-info
|
||||||
{{ prop.title }}
|
v-if="isArray(info?.child)"
|
||||||
</template>
|
:title="info.title"
|
||||||
<slot name="body"></slot>
|
:columns="info.child"
|
||||||
<a-card class="mt-2" :hoverable="true" v-for="info in layout">
|
:data="infoData"
|
||||||
<ma-info
|
ref="maInfoRefs"
|
||||||
v-if="isArray(info?.child)"
|
></ma-info>
|
||||||
:title="info.title"
|
<a-descriptions
|
||||||
:columns="info.child"
|
:title="info.title"
|
||||||
:data="infoData"
|
v-else
|
||||||
ref="maInfoRefs"
|
>
|
||||||
></ma-info>
|
<component
|
||||||
<a-descriptions :title="info.title" v-else>
|
:data="infoData"
|
||||||
<component :data="infoData" :is="info?.component" />
|
:is="info?.component"
|
||||||
</a-descriptions>
|
|
||||||
</a-card>
|
|
||||||
<ma-form
|
|
||||||
v-model="form"
|
|
||||||
ref="maFormRef"
|
|
||||||
v-if="prop.formColumns.length > 0"
|
|
||||||
:columns="prop.formColumns"
|
|
||||||
:options="{ showButtons: false, ...prop.formOptions }"
|
|
||||||
/>
|
/>
|
||||||
</a-modal>
|
</a-descriptions>
|
||||||
|
|
||||||
|
</a-card>
|
||||||
|
<ma-form
|
||||||
|
v-model="form"
|
||||||
|
ref="maFormRef"
|
||||||
|
v-if="prop.formColumns.length > 0"
|
||||||
|
:columns="prop.formColumns"
|
||||||
|
:options="{showButtons: false, ...prop.formOptions}"
|
||||||
|
/>
|
||||||
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import MaInfo from "../ma-info/index.vue"
|
import MaInfo from "../ma-info/index.vue";
|
||||||
import { getCurrentInstance, reactive, ref, watch } from "vue"
|
import {getCurrentInstance, reactive, ref, watch} from "vue";
|
||||||
import { isArray, isFunction, isObject, isString } from "lodash"
|
import {isArray, isFunction, isObject, isString} from "lodash";
|
||||||
import { isComponent } from "@arco-design/web-vue/es/_utils/vue-utils"
|
import {isComponent} from "@arco-design/web-vue/es/_utils/vue-utils";
|
||||||
const emit = defineEmits(["visible", "validateError", "open", "cancel", "close"])
|
import {setModalSizeEvent} from "@/utils/common";
|
||||||
|
const emit = defineEmits(["visible", "validateError", "open", "cancel", "close"]);
|
||||||
const app = getCurrentInstance().appContext.app
|
const app = getCurrentInstance().appContext.app
|
||||||
const maFormRef = ref()
|
const maFormRef = ref()
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: Number, default: 1200 }, // modal框大小
|
width: {type: Number, default: 1200}, // modal框大小
|
||||||
title: { type: String, default: "" }, // 弹出框标题
|
isFull: { type: Boolean, default: false},
|
||||||
column: { type: Array, default: [] }, // ma-form字段
|
title: { type: String, default: "" }, // 弹出框标题
|
||||||
default_visible: { type: Boolean, default: false }, // 默认隐藏
|
column: { type: Array, default: [] }, // ma-form字段
|
||||||
options: { type: Object, default: {} }, // ma-form 属性
|
default_visible: { type: Boolean, default: false}, // 默认隐藏
|
||||||
submit: { type: Function, default: () => {} },
|
options: { type: Object, default: {} }, // ma-form 属性
|
||||||
layout: { type: Object, default: [] },
|
submit: { type: Function, default: () => {} },
|
||||||
formOptions: { type: Object, default: {} }, // ma-form-options
|
layout: { type: Object, default:[]},
|
||||||
formColumns: { type: Array, default: [] }
|
formOptions: {type: Object, default: {}}, // ma-form-options
|
||||||
|
formColumns: { type: Array, default: []}
|
||||||
|
});
|
||||||
|
const isFull = ref(prop.isFull)
|
||||||
|
setModalSizeEvent((config) => {
|
||||||
|
isFull.value = config.isFull
|
||||||
})
|
})
|
||||||
|
|
||||||
const maInfoRefs = ref([])
|
const maInfoRefs = ref([])
|
||||||
const layout = ref([])
|
const layout = ref([])
|
||||||
const infoData = ref({})
|
const infoData = ref({})
|
||||||
const form = ref({})
|
const form = ref({})
|
||||||
|
|
||||||
watch(
|
watch(() => prop.layout, val => {
|
||||||
() => prop.layout,
|
layout.value = val
|
||||||
(val) => {
|
},{
|
||||||
layout.value = val
|
immediate: true,
|
||||||
},
|
})
|
||||||
{
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
let columnMap = {}
|
let columnMap = {}
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
let column = prop.column
|
let column = prop.column
|
||||||
column.forEach((item) => {
|
column.forEach(item => {
|
||||||
columnMap[item.dataIndex] = item
|
columnMap[item.dataIndex] = item
|
||||||
|
})
|
||||||
|
if (layout.value.length > 0) {
|
||||||
|
layout.value.forEach((item) => {
|
||||||
|
if (item.component) {
|
||||||
|
app.component(item.component, item.child)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
item.child.forEach((child, index) => {
|
||||||
|
if (isString(child)) {
|
||||||
|
item.child[index] = columnMap[child]
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
if (layout.value.length > 0) {
|
}else{
|
||||||
layout.value.forEach((item) => {
|
layout.value.push({
|
||||||
if (item.component) {
|
title: "",
|
||||||
app.component(item.component, item.child)
|
child: column,
|
||||||
return
|
})
|
||||||
}
|
}
|
||||||
item.child.forEach((child, index) => {
|
|
||||||
if (isString(child)) {
|
|
||||||
item.child[index] = columnMap[child]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
layout.value.push({
|
|
||||||
title: "",
|
|
||||||
child: column
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const modal = reactive({
|
const modal = reactive({
|
||||||
visible: prop.default_visible,
|
visible: prop.default_visible,
|
||||||
open(data, formData = {}) {
|
open(data, formData = {}) {
|
||||||
modal.visible = true
|
modal.visible = true;
|
||||||
for (let [key, value] of Object.entries(data)) {
|
for (let [key, value] of Object.entries(data)) {
|
||||||
infoData.value[key] = value
|
infoData.value[key] = value;
|
||||||
}
|
|
||||||
for (let [key, value] of Object.entries(formData)) {
|
|
||||||
form.value[key] = value
|
|
||||||
}
|
|
||||||
emit("open", infoData)
|
|
||||||
},
|
|
||||||
close() {
|
|
||||||
modal.visible = false
|
|
||||||
},
|
|
||||||
async submit() {
|
|
||||||
let validate = await maFormRef.value.validateForm()
|
|
||||||
if (validate) {
|
|
||||||
emit("validateError", validate)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return prop.submit(form._rawValue)
|
|
||||||
},
|
|
||||||
cancel() {
|
|
||||||
emit("cancel")
|
|
||||||
}
|
}
|
||||||
})
|
for (let [key, value] of Object.entries(formData)) {
|
||||||
|
form.value[key] = value;
|
||||||
|
}
|
||||||
|
emit("open", infoData);
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
modal.visible = false;
|
||||||
|
},
|
||||||
|
async submit() {
|
||||||
|
let validate = await maFormRef.value.validateForm()
|
||||||
|
if (validate) {
|
||||||
|
emit("validateError", validate)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return prop.submit(form._rawValue)
|
||||||
|
},
|
||||||
|
cancel() {
|
||||||
|
emit("cancel");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
init()
|
init()
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
open: modal.open,
|
open: modal.open,
|
||||||
close: modal.close,
|
close: modal.close,
|
||||||
data: infoData
|
data: infoData,
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1,129 +1,122 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-space direction="vertical" size="large" fill>
|
<a-space direction="vertical" size="large" fill>
|
||||||
<a-descriptions
|
<a-descriptions
|
||||||
:data="descriptions"
|
:data="descriptions"
|
||||||
:column="props.column"
|
:column="props.column"
|
||||||
:title="props.title"
|
:title="props.title"
|
||||||
:layout="props.layout"
|
:layout="props.layout"
|
||||||
:bordered="props.bordered"
|
:bordered="props.bordered"
|
||||||
table-layout="auto"
|
table-layout="fixed"
|
||||||
:size="props.size"
|
:size="props.size"
|
||||||
:label-style="props.labelStyle"
|
:label-style="props.labelStyle"
|
||||||
:value-style="props.valueStyle"
|
:value-style="props.valueStyle"
|
||||||
>
|
>
|
||||||
<a-descriptions-item v-for="item in descriptions" :label="item.label">
|
<a-descriptions-item v-for="item in descriptions" :label="item.label">
|
||||||
<template v-if="item.formType === 'upload'">
|
<template v-if="item.formType === 'upload'">
|
||||||
<a-image-preview-group infinite v-if="isArray(item.value)">
|
<a-image-preview-group infinite v-if="isArray(item.value)">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-image v-for="src in item.value" :src="tool.viewImage(src)" width="50" />
|
<a-image v-for="src in item.value" :src="tool.viewImage(src)" width="50" />
|
||||||
</a-space>
|
</a-space>
|
||||||
</a-image-preview-group>
|
</a-image-preview-group>
|
||||||
<a-image v-else :src="tool.viewImage(item.value)" width="50"></a-image>
|
<a-image v-else :src="tool.viewImage(item.value)" width="50"></a-image>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.infoSlot">
|
<template v-else-if="item.infoSlot">
|
||||||
<slot :name="item.dataIndex" :row="item" :data="data"></slot>
|
<slot :name="item.dataIndex" :row="item" :data="data"></slot>
|
||||||
</template>
|
</template>
|
||||||
<template
|
<template v-else-if="item.formType === 'radio' || item.formType === 'select'">
|
||||||
v-else-if="(item.multiple === true && item.formType === 'select') || item.formType === 'checkbox'"
|
<a-tag color="blue">{{
|
||||||
>
|
item.dict.data.find((row) => row.value == item.value)?.label
|
||||||
<a-space size="mini"
|
}}</a-tag>
|
||||||
><a-tag color="pinkpurple" v-for="subItem in item.value" :key="subItem">
|
</template>
|
||||||
{{ item.dict.data.find((row) => row.value == subItem)?.label }}
|
<div v-else>{{ item.value }} {{ item?.textAppend }}</div>
|
||||||
</a-tag>
|
</a-descriptions-item>
|
||||||
</a-space>
|
</a-descriptions>
|
||||||
</template>
|
</a-space>
|
||||||
<template v-else-if="item.formType === 'radio' || item.formType === 'select'">
|
|
||||||
<a-tag color="blue">{{ item.dict.data.find((row) => row.value == item.value)?.label }}</a-tag>
|
|
||||||
</template>
|
|
||||||
<div v-else>{{ item.value }} {{ item?.textAppend }}</div>
|
|
||||||
</a-descriptions-item>
|
|
||||||
</a-descriptions>
|
|
||||||
</a-space>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getCurrentInstance, inject, provide, ref, watch } from "vue"
|
import { getCurrentInstance, inject, provide, ref, watch } from "vue";
|
||||||
import tool from "@/utils/tool"
|
import tool from "@/utils/tool";
|
||||||
import { get, isArray, isBoolean, isEmpty, isFunction } from "lodash"
|
import { get, isArray, isBoolean, isEmpty, isFunction } from "lodash";
|
||||||
import { loadDict } from "@cps/ma-form/js/networkRequest.js"
|
import { loadDict } from "@cps/ma-form/js/networkRequest.js";
|
||||||
import globalColumn from "@/config/column.js"
|
import globalColumn from "@/config/column.js";
|
||||||
|
|
||||||
const dictList = {}
|
const dictList = {};
|
||||||
const app = getCurrentInstance().appContext.app
|
const app = getCurrentInstance().appContext.app;
|
||||||
const columns = ref([])
|
const columns = ref([]);
|
||||||
const data = ref({})
|
const data = ref({});
|
||||||
const descriptions = ref([])
|
const descriptions = ref([]);
|
||||||
const dictData = ref([])
|
const dictData = ref([]);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
columns: { type: Array, default: [] },
|
columns: { type: Array, default: [] },
|
||||||
data: {},
|
data: {},
|
||||||
column: { default: 3 },
|
column: { default: 3 },
|
||||||
title: {
|
title: {
|
||||||
default: ""
|
default: "",
|
||||||
},
|
},
|
||||||
bordered: {
|
bordered: {
|
||||||
default: true
|
default: true,
|
||||||
},
|
},
|
||||||
layout: {
|
layout: {
|
||||||
default: "vertical"
|
default: "vertical",
|
||||||
},
|
},
|
||||||
labelStyle: {
|
labelStyle: {
|
||||||
default: {}
|
default: {},
|
||||||
},
|
},
|
||||||
valueStyle: {
|
valueStyle: {
|
||||||
default: {}
|
default: {},
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default: "large"
|
default: "large",
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.columns,
|
() => props.columns,
|
||||||
(vl) => {
|
(vl) => {
|
||||||
columns.value = vl
|
columns.value = vl;
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true }
|
||||||
)
|
);
|
||||||
|
|
||||||
const reset = (vl) => {
|
const reset = async (vl) => {
|
||||||
data.value = vl
|
data.value = vl;
|
||||||
descriptions.value = []
|
descriptions.value = [];
|
||||||
if (!columns.value) {
|
if (!columns.value) {
|
||||||
return
|
return;
|
||||||
|
}
|
||||||
|
for (let item of columns.value) {
|
||||||
|
let value = null;
|
||||||
|
if (isEmpty(item) || item.dataIndex === "__operation" || item.infoShow === false) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
columns.value.forEach(async (item) => {
|
if (isBoolean(item.common) && item.common && globalColumn[item.dataIndex]) {
|
||||||
let value = null
|
item = globalColumn[item.dataIndex];
|
||||||
if (isEmpty(item) || item.dataIndex === "__operation" || item.infoShow === false) {
|
}
|
||||||
return
|
if (item.dict) {
|
||||||
}
|
await loadDict(dictList, item);
|
||||||
if (isBoolean(item.common) && item.common && globalColumn[item.dataIndex]) {
|
item.dict.data = dictList[item.dataIndex] ?? [];
|
||||||
item = globalColumn[item.dataIndex]
|
}
|
||||||
}
|
if (isFunction(item.customRender)) {
|
||||||
if (item.dict) {
|
value = item.customRender({ record: data.value });
|
||||||
await loadDict(dictList, item)
|
}
|
||||||
item.dict.data = dictList[item.dataIndex] ?? []
|
descriptions.value.push({
|
||||||
}
|
...item,
|
||||||
if (isFunction(item.customRender)) {
|
label: item.title,
|
||||||
value = item.customRender({ record: data.value })
|
value: value ?? get(data.value, item.dataIndex),
|
||||||
}
|
});
|
||||||
descriptions.value.push({
|
};
|
||||||
...item,
|
};
|
||||||
label: item.title,
|
|
||||||
value: value ?? get(data.value, item.dataIndex)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.data,
|
() => props.data,
|
||||||
(vl) => {
|
(vl) => {
|
||||||
reset(vl)
|
reset(vl);
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true }
|
||||||
)
|
);
|
||||||
|
|
||||||
defineExpose({ reset })
|
defineExpose({ reset });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
@@ -1,88 +1,81 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="inline-block">
|
<div class="inline-block">
|
||||||
<a-input-group class="w-full">
|
<a-input-group class="w-full">
|
||||||
<a-trigger position="bottom" auto-fit-position :unmount-on-close="false">
|
<a-trigger position="bottom" auto-fit-position :unmount-on-close="false">
|
||||||
<a-input v-model="inputValue" placeholder="请点击左侧按钮选择资源" readonly v-if="!props.multiple" />
|
<a-input v-model="inputValue" placeholder="请点击左侧按钮选择资源" readonly v-if="! props.multiple" />
|
||||||
<a-button v-else>预览已选</a-button>
|
<a-button v-else>预览已选</a-button>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="trigger-content">
|
<div class="trigger-content">
|
||||||
<a-empty v-if="list && list.length == 0" />
|
<a-empty v-if="list && list.length == 0" />
|
||||||
<a-image :src="inputValue" v-else-if="list && !isArray(list)" />
|
<a-image :src="inputValue" v-else-if="list && ! isArray(list)" />
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<a-image-preview-group infinite>
|
<a-image-preview-group infinite>
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-image :src="item" v-for="(item, index) in list" width="100%" :key="index" />
|
<a-image :src="item" v-for="(item, index) in list" width="100%" :key="index" />
|
||||||
</a-space>
|
</a-space>
|
||||||
</a-image-preview-group>
|
</a-image-preview-group>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-trigger>
|
</a-trigger>
|
||||||
<a-button type="primary" @click="visible = true"><icon-experiment /> 资源选择器</a-button>
|
<a-button type="primary" @click="visible = true"><icon-experiment /> 资源选择器</a-button>
|
||||||
</a-input-group>
|
</a-input-group>
|
||||||
<a-modal v-model:visible="visible" :width="props.width" :footer="false" draggable>
|
<a-modal v-model:visible="visible" :width="props.width" :footer="false" draggable>
|
||||||
<template #title>资源选择器</template>
|
<template #title>资源选择器</template>
|
||||||
<ma-resource v-model="list" :multiple="props.multiple" :only-data="props.onlyData" />
|
<ma-resource v-model="list" :multiple="props.multiple" :only-data="props.onlyData" />
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref, watch } from "vue"
|
import { onMounted, ref, watch } from 'vue'
|
||||||
import MaResource from "@cps/ma-resource/index.vue"
|
import MaResource from '@cps/ma-resource/index.vue'
|
||||||
import { isArray } from "lodash"
|
import { isArray } from 'lodash'
|
||||||
|
|
||||||
const list = ref()
|
const list = ref()
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const inputValue = ref("")
|
const inputValue = ref('')
|
||||||
|
|
||||||
const emit = defineEmits(["update:modelValue"])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: { type: [String, Array] },
|
modelValue: { type: [ String, Array ] },
|
||||||
multiple: { type: Boolean, default: true },
|
multiple: { type: Boolean, default: true },
|
||||||
onlyData: { type: Boolean, default: true },
|
onlyData: { type: Boolean, default: true },
|
||||||
width: { type: Number, default: 1080 }
|
width: { type: Number, default: 1080 },
|
||||||
})
|
})
|
||||||
|
|
||||||
list.value = props.modelValue
|
list.value = props.modelValue
|
||||||
// onMounted(() => )
|
// onMounted(() => )
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => list.value,
|
() => list.value,
|
||||||
(vl) => {
|
vl => {
|
||||||
emit("update:modelValue", list.value)
|
emit('update:modelValue', list.value)
|
||||||
if (props.multiple) {
|
if ( props.multiple ) {
|
||||||
console.log(vl)
|
inputValue.value = isArray(list) ? list.value.join(',') : []
|
||||||
inputValue.value = isArray(list) ? list.value.join(",") : []
|
} else {
|
||||||
} else {
|
inputValue.value = list.value
|
||||||
inputValue.value = list.value
|
}
|
||||||
}
|
visible.value = false
|
||||||
visible.value = false
|
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.trigger-content {
|
.trigger-content {
|
||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
background: var(--color-fill-1);
|
background: var(--color-fill-1);
|
||||||
border: 1px solid var(--color-fill-3);
|
border: 1px solid var(--color-fill-3);
|
||||||
width: 340px;
|
width: 340px;
|
||||||
border-radius: var(--border-radius-medium);
|
border-radius: var(--border-radius-medium);
|
||||||
}
|
}
|
||||||
:deep(.arco-space) {
|
:deep(.arco-space) {
|
||||||
display: block;
|
display: block; margin-bottom: 5px;
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full p-2 resource-container h-full lg:flex lg:justify-between rounded-sm">
|
<div class="w-full p-2 resource-container h-full lg:flex lg:justify-between rounded-sm">
|
||||||
<a-modal v-model:visible="openNetworkModal" ok-text="保存" :on-before-ok="saveNetworkImg" draggable>
|
<a-modal v-model:visible="openNetworkModal" :ok-text="$t('sys.save')" :on-before-ok="saveNetworkImg" draggable>
|
||||||
<template #title>保存网络图片</template>
|
<template #title>{{ $t("maResource.saveNetworkImage") }}</template>
|
||||||
<a-input v-model="networkImg" class="mb-3" placeholder="请粘贴网络图片地址" allow-clear />
|
<a-input v-model="networkImg" class="mb-3" :placeholder="$t('maResource.networkImageNotice')" allow-clear />
|
||||||
<a-image :src="networkImg" width="100%" style="min-height: 150px" />
|
<a-image :src="networkImg ?? ''" width="100%" style="min-height: 150px" />
|
||||||
</a-modal>
|
</a-modal>
|
||||||
<div class="lg:w-1/5 w-full p-2 shadow">
|
<div class="lg:w-1/5 w-full p-2 shadow">
|
||||||
<ma-tree-slider
|
<ma-tree-slider
|
||||||
v-model="sliderData"
|
:data="sliderData"
|
||||||
search-placeholder="搜索资源类型"
|
:search-placeholder="$t('maResource.searchResource')"
|
||||||
:field-names="{ title: 'title', key: 'key' }"
|
:field-names="{ title: 'title', key: 'key' }"
|
||||||
@click="handlerClick"
|
@click="handlerClick"
|
||||||
icon="icon-folder"
|
icon="icon-folder"
|
||||||
:selected-keys="['all']"
|
v-model="defaultKey"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full lg:ml-3 mt-3 lg:mt-2 flex flex-col">
|
<div class="w-full lg:ml-3 mt-3 lg:mt-2 flex flex-col">
|
||||||
@@ -20,17 +24,17 @@
|
|||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ma-upload v-model="uploadFile" multiple :show-list="false" type="chunk" :resource="false" />
|
<ma-upload v-model="uploadFile" multiple :show-list="false" type="chunk" :resource="false" />
|
||||||
<a-button class="ml-3" @click="openNetworkModal = true">
|
<a-button class="ml-3" @click="openNetworkModal = true">
|
||||||
<icon-image /> 保存网络图片
|
<icon-image /> {{ $t("maResource.saveNetworkImage") }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
<a-input
|
<a-input
|
||||||
v-model="filename"
|
v-model="filename"
|
||||||
class="input-search lg:mt-0 mt-2"
|
class="input-search lg:mt-0 mt-2"
|
||||||
placeholder="文件名搜索"
|
:placeholder="$t('maResource.searchFileNotice')"
|
||||||
@press-enter="searchFile"
|
@press-enter="searchFile"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<a-spin :loading="resourceLoading" tip="数据加载中..." class="h-full">
|
<a-spin :loading="resourceLoading" :tip="$t('maResource.loadingText')" class="h-full">
|
||||||
<div class="resource-list mt-2" ref="rl" v-if="attachmentList && attachmentList.length > 0">
|
<div class="resource-list mt-2" ref="rl" v-if="attachmentList && attachmentList.length > 0">
|
||||||
<div
|
<div
|
||||||
class="item rounded-sm"
|
class="item rounded-sm"
|
||||||
@@ -72,7 +76,9 @@
|
|||||||
v-model:page-size="pageSize"
|
v-model:page-size="pageSize"
|
||||||
@change="changePage"
|
@change="changePage"
|
||||||
/>
|
/>
|
||||||
<a-button type="primary" @click="selectComplete" class="mt-3 lg:mt-0">选择完成</a-button>
|
<a-button type="primary" @click="selectComplete" class="mt-3 lg:mt-0">{{
|
||||||
|
$t("maResource.ok")
|
||||||
|
}}</a-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -84,10 +90,13 @@ import MaUpload from "@cps/ma-upload/index.vue"
|
|||||||
import uploadConfig from "@/config/upload"
|
import uploadConfig from "@/config/upload"
|
||||||
import MaTreeSlider from "@cps/ma-treeSlider/index.vue"
|
import MaTreeSlider from "@cps/ma-treeSlider/index.vue"
|
||||||
import commonApi from "@/api/common"
|
import commonApi from "@/api/common"
|
||||||
|
import { xor } from "lodash"
|
||||||
import tool from "@/utils/tool"
|
import tool from "@/utils/tool"
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
const sliderData = ref([])
|
const sliderData = ref([])
|
||||||
|
const defaultKey = ref(["all"])
|
||||||
const uploadFile = ref()
|
const uploadFile = ref()
|
||||||
const attachmentList = ref([])
|
const attachmentList = ref([])
|
||||||
const openNetworkModal = ref(false)
|
const openNetworkModal = ref(false)
|
||||||
@@ -108,7 +117,7 @@ const props = defineProps({
|
|||||||
modelValue: { type: [String, Array] },
|
modelValue: { type: [String, Array] },
|
||||||
multiple: { type: Boolean, default: true },
|
multiple: { type: Boolean, default: true },
|
||||||
onlyData: { type: Boolean, default: true },
|
onlyData: { type: Boolean, default: true },
|
||||||
returnType: { type: String, default: "url" }
|
returnType: { type: String, default: "hash" }
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
@@ -140,6 +149,7 @@ const handlerItemClick = (e) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handlerClick = async (item) => {
|
const handlerClick = async (item) => {
|
||||||
|
defaultKey.value = item
|
||||||
const type = item[0] === "all" ? undefined : item[0]
|
const type = item[0] === "all" ? undefined : item[0]
|
||||||
await getAttachmentList({ mime_type: type })
|
await getAttachmentList({ mime_type: type })
|
||||||
}
|
}
|
||||||
@@ -149,13 +159,9 @@ const searchFile = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const selectFile = (item, index) => {
|
const selectFile = (item, index) => {
|
||||||
if (!props.multiple && selecteds.value) {
|
|
||||||
if (props.onlyData && item.url != selecteds.value) return
|
|
||||||
if (!props.onlyData && item.id != selecteds.value.id) return
|
|
||||||
}
|
|
||||||
|
|
||||||
const children = rl.value.children
|
const children = rl.value.children
|
||||||
const className = "item rounded-sm"
|
const className = "item rounded-sm"
|
||||||
|
|
||||||
if (!/^(http|https)/g.test(item.url)) {
|
if (!/^(http|https)/g.test(item.url)) {
|
||||||
item.url = tool.attachUrl(item.url, getStoreMode(item.storage_mode))
|
item.url = tool.attachUrl(item.url, getStoreMode(item.storage_mode))
|
||||||
}
|
}
|
||||||
@@ -163,18 +169,20 @@ const selectFile = (item, index) => {
|
|||||||
children[index].className = className
|
children[index].className = className
|
||||||
if (props.multiple) {
|
if (props.multiple) {
|
||||||
selecteds.value.map((file, idx) => {
|
selecteds.value.map((file, idx) => {
|
||||||
if (props.onlyData && file == item.url) selecteds.value.splice(idx, 1)
|
selecteds.value.splice(idx, 1)
|
||||||
if (!props.onlyData && file.id == item.id) selecteds.value.splice(idx, 1)
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
selecteds.value = ""
|
selecteds.value = ""
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
children[index].className = className + " active"
|
|
||||||
if (props.multiple) {
|
if (props.multiple) {
|
||||||
|
children[index].className = className + " active"
|
||||||
selecteds.value.push(props.onlyData ? item[props.returnType] : item)
|
selecteds.value.push(props.onlyData ? item[props.returnType] : item)
|
||||||
} else {
|
} else {
|
||||||
selecteds.value = props.onlyData ? item[props.returnType] : item
|
if (document.querySelectorAll(".item.active").length < 1) {
|
||||||
|
children[index].className = className + " active"
|
||||||
|
selecteds.value = props.onlyData ? item[props.returnType] : item
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,7 +212,7 @@ const changePage = async (page) => {
|
|||||||
|
|
||||||
const saveNetworkImg = async (done) => {
|
const saveNetworkImg = async (done) => {
|
||||||
if (!networkImg.value) {
|
if (!networkImg.value) {
|
||||||
Message.error("请粘贴网络图片地址")
|
Message.error(t("maResource.networkImageNotice"))
|
||||||
done(false)
|
done(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,112 +1,114 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col w-full h-full">
|
<div class="flex flex-col w-full h-full">
|
||||||
<a-input-group class="mb-2 w-full flex items-center" size="mini">
|
<a-input-group class="mb-2 w-full" size="mini">
|
||||||
<a-input
|
<a-input
|
||||||
:placeholder="props?.searchPlaceholder"
|
:placeholder="props?.searchPlaceholder"
|
||||||
allow-clear
|
allow-clear
|
||||||
@input="changeKeyword"
|
@input="changeKeyword"
|
||||||
@clear="resetData"
|
@clear="resetData"
|
||||||
style="height: 100%"
|
/>
|
||||||
/>
|
<a-button
|
||||||
<a-button
|
@click="() => {
|
||||||
@click="
|
isExpand ? maTree.expandAll(false) : maTree.expandAll(true)
|
||||||
() => {
|
isExpand = ! isExpand
|
||||||
isExpand ? maTree.expandAll(false) : maTree.expandAll(true)
|
}"
|
||||||
isExpand = !isExpand
|
>{{ isExpand ? '折叠' : '展开' }}</a-button>
|
||||||
}
|
</a-input-group>
|
||||||
"
|
<a-tree
|
||||||
>{{ isExpand ? "折叠" : "展开" }}</a-button
|
blockNode
|
||||||
>
|
ref="maTree"
|
||||||
</a-input-group>
|
:data="treeData"
|
||||||
<a-tree
|
class="h-full w-full"
|
||||||
blockNode
|
@select="handlerSelect"
|
||||||
:data="treeData"
|
:field-names="props.fieldNames"
|
||||||
class="h-full w-full"
|
v-model:selected-keys="modelValue"
|
||||||
@select="handlerSelect"
|
v-bind="$attrs"
|
||||||
:field-names="props.fieldNames"
|
>
|
||||||
v-model:selected-keys="selectedKeys"
|
<template #icon v-if="props.icon"><component :is="props.icon" /></template>
|
||||||
ref="maTree"
|
</a-tree>
|
||||||
v-bind="$attrs"
|
</div>
|
||||||
>
|
|
||||||
<template #icon v-if="props.icon"><component :is="props.icon" /></template>
|
|
||||||
</a-tree>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, onMounted } from "vue"
|
import { ref, watch, computed } from 'vue'
|
||||||
|
|
||||||
const treeData = ref([])
|
const treeData = ref([])
|
||||||
const selectedKeys = ref([])
|
const maTree = ref()
|
||||||
const maTree = ref()
|
const isExpand = ref(false)
|
||||||
const isExpand = ref(false)
|
|
||||||
|
|
||||||
const emit = defineEmits(["click"])
|
const emit = defineEmits(['update:modelValue', 'click'])
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: { type: Array },
|
modelValue: { type: Array },
|
||||||
|
data: { type: Array },
|
||||||
searchPlaceholder: { type: String },
|
searchPlaceholder: { type: String },
|
||||||
selectedKeys: { type: Array },
|
fieldNames: { type: Object, default: () => { return { title: 'label', key: 'value' } } },
|
||||||
fieldNames: {
|
icon: { type: String, default: undefined },
|
||||||
type: Object,
|
})
|
||||||
default: () => {
|
|
||||||
return { title: "label", value: "code" }
|
const modelValue = computed({
|
||||||
}
|
get() {
|
||||||
|
return props.modelValue
|
||||||
},
|
},
|
||||||
icon: { type: String, default: undefined }
|
set(newVal) {
|
||||||
})
|
emit('update:modelValue', newVal)
|
||||||
|
|
||||||
onMounted(() => (selectedKeys.value = props.selectedKeys))
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.modelValue,
|
|
||||||
(val) => {
|
|
||||||
treeData.value = val
|
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
|
|
||||||
const handlerSelect = (item, data) => {
|
watch(
|
||||||
selectedKeys.value = [item]
|
() => props.data,
|
||||||
emit("click", ...[item, data])
|
val => {
|
||||||
}
|
treeData.value = val
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
const resetData = () => (treeData.value = props.modelValue)
|
const handlerSelect = (item, data) => {
|
||||||
|
modelValue.value = [ item ]
|
||||||
|
emit('click', ...[item, data])
|
||||||
|
}
|
||||||
|
|
||||||
const changeKeyword = (keyword) => {
|
const resetData = () => treeData.value = props.data
|
||||||
if (!keyword || keyword === "") {
|
|
||||||
treeData.value = Object.assign(props.modelValue, [])
|
const changeKeyword = (keyword) => {
|
||||||
return false
|
if (!keyword || keyword === '') {
|
||||||
|
treeData.value = Object.assign(props.data, [])
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
treeData.value = searchNode(keyword)
|
treeData.value = searchNode(keyword)
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchNode = (keyword) => {
|
const searchNode = (keyword) => {
|
||||||
const loop = (data) => {
|
const loop = (data) => {
|
||||||
let tree = []
|
let tree = []
|
||||||
data.map((item) => {
|
data.map(item => {
|
||||||
if (item.children && item.children.length > 0) {
|
if (item.children && item.children.length > 0) {
|
||||||
const temp = loop(item.children)
|
const temp = loop(item.children)
|
||||||
tree.push(...temp)
|
tree.push(...temp)
|
||||||
} else if (item[props.fieldNames["title"]].indexOf(keyword) !== -1) {
|
} else if (item[props.fieldNames['title']].indexOf(keyword) !== -1) {
|
||||||
tree.push(item)
|
tree.push(item)
|
||||||
}
|
}
|
||||||
return tree
|
|
||||||
})
|
|
||||||
|
|
||||||
return tree
|
return tree
|
||||||
}
|
})
|
||||||
return loop(props.modelValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
defineExpose({ maTree })
|
return tree
|
||||||
|
}
|
||||||
|
return loop(treeData.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ maTree })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
:deep(.arco-tree-node:hover) {
|
:deep(.arco-tree-node:hover) {
|
||||||
background-color: var(--color-fill-2);
|
background-color: var(--color-fill-2);
|
||||||
border-radius: 2px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
:deep(.arco-tree-node-switcher) {
|
:deep(.arco-tree-node-switcher) {
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -18,9 +18,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<icon-upload class="text-5xl text-gray-400" />
|
<icon-upload class="text-5xl text-gray-400" />
|
||||||
<div class="text-red-600 font-bold">
|
<div class="text-red-600 font-bold">
|
||||||
{{ config.title === "buttonText" ? '本地上传' : config.title }}
|
{{ config.title === "buttonText" ? $t("upload.buttonText") : config.title }}
|
||||||
</div>
|
</div>
|
||||||
将文件拖到此处,或<span style="color: #3370ff">点击上传</span>
|
{{ $t("upload.uploadDesc") }}<span style="color: #3370ff">{{ $t("upload.clickUpload") }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</slot>
|
</slot>
|
||||||
@@ -35,17 +35,26 @@
|
|||||||
animation
|
animation
|
||||||
type="circle"
|
type="circle"
|
||||||
size="mini"
|
size="mini"
|
||||||
|
show-text
|
||||||
class="progress"
|
class="progress"
|
||||||
/>
|
/>
|
||||||
<a-button class="delete" @click="removeSignFile()" v-if="currentItem.percent === 100">
|
<span v-if="currentItem.percent < 100">上传中...</span>
|
||||||
<template #icon><icon-delete /></template>
|
|
||||||
|
<a-tooltip content="点击文件名预览/下载" position="tr">
|
||||||
|
<a
|
||||||
|
:href="currentItem.url"
|
||||||
|
v-if="currentItem?.url && currentItem.percent === 100 && currentItem?.status === 'complete'"
|
||||||
|
class="file-name"
|
||||||
|
target="_blank"
|
||||||
|
>{{ currentItem.name }}</a
|
||||||
|
>
|
||||||
|
</a-tooltip>
|
||||||
|
|
||||||
|
<a-button type="text" size="small" @click="removeSignFile()" v-if="currentItem.percent === 100">
|
||||||
|
<template #icon>
|
||||||
|
<icon-delete />
|
||||||
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
<div
|
|
||||||
v-if="currentItem?.url && currentItem.percent === 100 && currentItem?.status === 'complete'"
|
|
||||||
class="file-item"
|
|
||||||
>
|
|
||||||
{{ currentItem.url }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 多文件 -->
|
<!-- 多文件 -->
|
||||||
@@ -58,26 +67,39 @@
|
|||||||
size="mini"
|
size="mini"
|
||||||
class="progress"
|
class="progress"
|
||||||
/>
|
/>
|
||||||
<a-button class="delete" @click="removeFile(idx)" v-if="file.percent === 100">
|
<span v-if="file.percent < 100">上传中...</span>
|
||||||
<template #icon><icon-delete /></template>
|
|
||||||
|
<a-tooltip content="点击文件名预览/下载" position="tr">
|
||||||
|
<a
|
||||||
|
:href="file.url"
|
||||||
|
v-if="file?.url && file.percent === 100 && file?.status === 'complete'"
|
||||||
|
class="file-name"
|
||||||
|
target="_blank"
|
||||||
|
>{{ file.name }}</a
|
||||||
|
>
|
||||||
|
</a-tooltip>
|
||||||
|
|
||||||
|
<a-button type="text" size="small" @click="removeFile(idx)" v-if="file.percent === 100">
|
||||||
|
<template #icon>
|
||||||
|
<icon-delete />
|
||||||
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
<div v-if="file?.url && file.percent === 100 && file?.status === 'complete'" class="file-item">
|
|
||||||
{{ file.url }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, watch } from "vue"
|
import { ref, inject, watch } from "vue"
|
||||||
import commonApi from "@/api/common"
|
import commonApi from "@/api/common"
|
||||||
import tool from "@/utils/tool"
|
import tool from "@/utils/tool"
|
||||||
import { isArray } from "lodash"
|
import { isArray, throttle } from "lodash"
|
||||||
import { getFileUrl } from "../js/utils"
|
import { getFileUrl } from "../js/utils"
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
import file2md5 from "file2md5"
|
import file2md5 from "file2md5"
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: { type: [String, Number, Array], default: () => {} }
|
modelValue: {
|
||||||
|
type: [String, Number, Array],
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(["update:modelValue"])
|
const emit = defineEmits(["update:modelValue"])
|
||||||
const config = inject("config")
|
const config = inject("config")
|
||||||
@@ -123,6 +145,7 @@ const chunkUpload = async (options) => {
|
|||||||
if (res.data && res.data.hash) {
|
if (res.data && res.data.hash) {
|
||||||
res.data.url = tool.attachUrl(res.data.url, storageMode[res.data.storage_mode])
|
res.data.url = tool.attachUrl(res.data.url, storageMode[res.data.storage_mode])
|
||||||
if (config.multiple) {
|
if (config.multiple) {
|
||||||
|
showFileList.value[idx].name = res.data.origin_name
|
||||||
showFileList.value[idx].percent = 100
|
showFileList.value[idx].percent = 100
|
||||||
showFileList.value[idx].status = "complete"
|
showFileList.value[idx].status = "complete"
|
||||||
showFileList.value[idx].url = res.data.url
|
showFileList.value[idx].url = res.data.url
|
||||||
@@ -145,7 +168,7 @@ const chunkUpload = async (options) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (res.data && res.data.code && res.data.code === 201) {
|
if (res.data && res.data.code && res.data.code === 201) {
|
||||||
const percent = parseFloat((1 / chunks).toFixed(2))
|
const percent = Math.floor((1 / chunks) * 10000) / 10000
|
||||||
if (config.multiple) {
|
if (config.multiple) {
|
||||||
showFileList.value[idx].percent += percent
|
showFileList.value[idx].percent += percent
|
||||||
} else {
|
} else {
|
||||||
@@ -175,32 +198,49 @@ const removeFile = (idx) => {
|
|||||||
emit("update:modelValue", files)
|
emit("update:modelValue", files)
|
||||||
}
|
}
|
||||||
|
|
||||||
const init = async () => {
|
const init = throttle(async () => {
|
||||||
if (config.multiple) {
|
if (config.multiple) {
|
||||||
if (isArray(props.modelValue) && props.modelValue.length > 0) {
|
if (isArray(props.modelValue) && props.modelValue.length > 0) {
|
||||||
const result = await props.modelValue.map(async (item) => {
|
const result = await props.modelValue.map(async (item) => {
|
||||||
return await getFileUrl(config.returnType, item, storageMode)
|
return await getFileUrl(config.returnType, item, storageMode)
|
||||||
})
|
})
|
||||||
const results = await Promise.all(result)
|
const data = await Promise.all(result)
|
||||||
showFileList.value = results.map((item) => {
|
|
||||||
return {
|
let fileItemObj = { percent: 100, status: "complete" }
|
||||||
...item,
|
if (config.returnType === "url") {
|
||||||
percent: 100,
|
showFileList.value = data.map((url) => {
|
||||||
status: "complete"
|
return { url, name: url.substring(url.lastIndexOf("/") + 1), ...fileItemObj }
|
||||||
}
|
})
|
||||||
})
|
} else {
|
||||||
|
showFileList.value = data.map((item) => {
|
||||||
|
return {
|
||||||
|
name: item.origin_name,
|
||||||
|
[config.returnType]: item[config.returnType],
|
||||||
|
url: item.url,
|
||||||
|
...fileItemObj
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
showFileList.value = []
|
showFileList.value = []
|
||||||
}
|
}
|
||||||
} else if (props.modelValue) {
|
} else if (props.modelValue) {
|
||||||
signFile.value = props.modelValue
|
if (config.returnType === "url") {
|
||||||
getFileUrl(config.returnType, props.modelValue, storageMode).then((item) => (currentItem.value.url = item))
|
signFile.value = props.modelValue
|
||||||
|
currentItem.value.url = props.modelValue
|
||||||
|
currentItem.value.name = props.modelValue?.substring((props.modelValue?.lastIndexOf("/") || 0) + 1)
|
||||||
|
} else {
|
||||||
|
const result = await getFileUrl(config.returnType, props.modelValue, storageMode)
|
||||||
|
signFile.value = result.url
|
||||||
|
currentItem.value.url = result.url
|
||||||
|
currentItem.value.name = result.origin_name
|
||||||
|
}
|
||||||
currentItem.value.percent = 100
|
currentItem.value.percent = 100
|
||||||
currentItem.value.status = "complete"
|
currentItem.value.status = "complete"
|
||||||
} else {
|
} else {
|
||||||
removeSignFile()
|
removeSignFile()
|
||||||
}
|
}
|
||||||
}
|
}, 1000)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
@@ -215,25 +255,21 @@ watch(
|
|||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.file-list {
|
.file-list {
|
||||||
position: relative;
|
|
||||||
background-color: var(--color-primary-light-1);
|
background-color: var(--color-primary-light-1);
|
||||||
border-radius: 2px;
|
border-radius: 4px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
line-height: 36px;
|
padding: 0 5px;
|
||||||
padding: 0 10px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.delete {
|
display: flex;
|
||||||
position: absolute;
|
flex-direction: row;
|
||||||
z-index: 99;
|
justify-content: space-between;
|
||||||
right: 2px;
|
align-items: center;
|
||||||
top: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress {
|
.file-name {
|
||||||
position: absolute;
|
max-width: 90%;
|
||||||
left: 30px;
|
margin: 0 5px;
|
||||||
top: 50%;
|
overflow: hidden;
|
||||||
transform: translateX(-50%) translateY(-50%);
|
color: #165dff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<icon-upload class="text-5xl text-gray-400" />
|
<icon-upload class="text-5xl text-gray-400" />
|
||||||
<div class="text-red-600 font-bold">
|
<div class="text-red-600 font-bold">
|
||||||
{{ config.title === "buttonText" ? "本地上传" : config.title }}
|
{{ config.title === "buttonText" ? $t("upload.buttonText") : config.title }}
|
||||||
</div>
|
</div>
|
||||||
将文件拖到此处,或<span style="color: #3370ff">点击上传</span>
|
将文件拖到此处,或<span style="color: #3370ff">点击上传</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -30,33 +30,48 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- 单文件 -->
|
<!-- 单文件 -->
|
||||||
<div class="file-list mt-2" v-if="!config.multiple && currentItem?.url && config.showList">
|
<div class="file-list mt-2" v-if="!config.multiple && currentItem?.url && config.showList">
|
||||||
<a-button class="delete" @click="removeSignFile()">
|
<a-tooltip content="点击文件名预览/下载" position="tr">
|
||||||
<template #icon><icon-delete /></template>
|
<a
|
||||||
|
:href="currentItem.url"
|
||||||
|
v-if="currentItem?.url && currentItem.percent === 100 && currentItem?.status === 'complete'"
|
||||||
|
class="file-name"
|
||||||
|
target="_blank"
|
||||||
|
>{{ currentItem.name }}</a
|
||||||
|
>
|
||||||
|
</a-tooltip>
|
||||||
|
|
||||||
|
<a-button type="text" size="small" @click="removeSignFile()" v-if="currentItem.percent === 100">
|
||||||
|
<template #icon>
|
||||||
|
<icon-delete />
|
||||||
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
<div class="file-item">
|
|
||||||
{{ currentItem.url }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 多文件 -->
|
<!-- 多文件 -->
|
||||||
<div v-if="config.showList" class="file-list mt-2" v-for="(file, idx) in showFileList" :key="idx">
|
<div v-if="config.showList" class="file-list mt-2" v-for="(file, idx) in showFileList" :key="idx">
|
||||||
<a-button class="delete" @click="removeFile(idx)">
|
<a-tooltip content="点击文件名预览/下载" position="tr">
|
||||||
<template #icon><icon-delete /></template>
|
<a :href="file.url" v-if="file?.url" class="file-name" target="_blank">{{ file.name }}</a>
|
||||||
|
</a-tooltip>
|
||||||
|
|
||||||
|
<a-button type="text" size="small" @click="removeFile(idx)">
|
||||||
|
<template #icon>
|
||||||
|
<icon-delete />
|
||||||
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
<div class="file-item">
|
|
||||||
{{ file.url }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, watch } from "vue"
|
import { ref, inject, watch } from "vue"
|
||||||
import tool from "@/utils/tool"
|
import tool from "@/utils/tool"
|
||||||
import { isArray } from "lodash"
|
import { isArray, throttle } from "lodash-es"
|
||||||
import { getFileUrl, uploadRequest } from "../js/utils"
|
import { getFileUrl, uploadRequest } from "../js/utils"
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: { type: [String, Number, Array], default: () => {} }
|
modelValue: {
|
||||||
|
type: [String, Number, Array],
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(["update:modelValue"])
|
const emit = defineEmits(["update:modelValue"])
|
||||||
const config = inject("config")
|
const config = inject("config")
|
||||||
@@ -72,7 +87,7 @@ const uploadFileHandler = async (options) => {
|
|||||||
}
|
}
|
||||||
const file = options.fileItem.file
|
const file = options.fileItem.file
|
||||||
if (file.size > config.size) {
|
if (file.size > config.size) {
|
||||||
Message.warning(file.name + " " + "文件大小超过了限制")
|
Message.warning(file.name + " " + t("upload.sizeLimit"))
|
||||||
currentItem.value = {}
|
currentItem.value = {}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -111,25 +126,45 @@ const removeFile = (idx) => {
|
|||||||
emit("update:modelValue", files)
|
emit("update:modelValue", files)
|
||||||
}
|
}
|
||||||
|
|
||||||
const init = async () => {
|
const init = throttle(async () => {
|
||||||
if (config.multiple) {
|
if (config.multiple) {
|
||||||
if (isArray(props.modelValue) && props.modelValue.length > 0) {
|
if (isArray(props.modelValue) && props.modelValue.length > 0) {
|
||||||
const result = await props.modelValue.map(async (item) => {
|
const result = await props.modelValue.map(async (item) => {
|
||||||
return await getFileUrl(config.returnType, item, storageMode)
|
return await getFileUrl(config.returnType, item, storageMode)
|
||||||
})
|
})
|
||||||
showFileList.value = await Promise.all(result)
|
const data = await Promise.all(result)
|
||||||
|
if (config.returnType === "url") {
|
||||||
|
showFileList.value = data.map((url) => {
|
||||||
|
return { url, name: url.substring(url.lastIndexOf("/") + 1) }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
showFileList.value = data.map((item) => {
|
||||||
|
return {
|
||||||
|
url: item.url,
|
||||||
|
[config.returnType]: item[config.returnType],
|
||||||
|
name: item.origin_name
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
showFileList.value = []
|
showFileList.value = []
|
||||||
}
|
}
|
||||||
} else if (props.modelValue) {
|
} else if (props.modelValue) {
|
||||||
signFile.value = props.modelValue
|
if (config.returnType === "url") {
|
||||||
getFileUrl(config.returnType, props.modelValue, storageMode).then((item) => (currentItem.value.url = item))
|
signFile.value = props.modelValue
|
||||||
|
currentItem.value.url = props.modelValue
|
||||||
|
} else {
|
||||||
|
const result = await getFileUrl(config.returnType, props.modelValue, storageMode)
|
||||||
|
signFile.value = result.url
|
||||||
|
currentItem.value.url = result.url
|
||||||
|
currentItem.value.name = result.origin_name
|
||||||
|
}
|
||||||
currentItem.value.percent = 100
|
currentItem.value.percent = 100
|
||||||
currentItem.value.status = "complete"
|
currentItem.value.status = "complete"
|
||||||
} else {
|
} else {
|
||||||
removeSignFile()
|
removeSignFile()
|
||||||
}
|
}
|
||||||
}
|
}, 1000)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
@@ -145,25 +180,21 @@ watch(
|
|||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.file-list {
|
.file-list {
|
||||||
position: relative;
|
|
||||||
background-color: var(--color-primary-light-1);
|
background-color: var(--color-primary-light-1);
|
||||||
border-radius: 2px;
|
border-radius: 4px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
line-height: 36px;
|
padding: 0 5px;
|
||||||
padding: 0 10px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.delete {
|
display: flex;
|
||||||
position: absolute;
|
flex-direction: row;
|
||||||
z-index: 99;
|
justify-content: space-between;
|
||||||
right: 2px;
|
align-items: center;
|
||||||
top: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress {
|
.file-name {
|
||||||
position: absolute;
|
max-width: 90%;
|
||||||
left: 30px;
|
margin: 0 5px;
|
||||||
top: 50%;
|
overflow: hidden;
|
||||||
transform: translateX(-50%) translateY(-50%);
|
color: #165dff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,63 +1,79 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="upload-image flex">
|
<div class="upload-image flex">
|
||||||
<!-- 单图 -->
|
<!-- 单图 -->
|
||||||
<div
|
<a-space wrap>
|
||||||
:class="'image-list ' + (config.rounded ? 'rounded-full' : '')"
|
|
||||||
v-if="!config.multiple && currentItem?.url && config.showList"
|
|
||||||
>
|
|
||||||
<a-button class="delete" @click="removeSignImage()">
|
|
||||||
<template #icon><icon-delete /></template>
|
|
||||||
</a-button>
|
|
||||||
<a-image width="130" height="130" :class="config.rounded ? 'rounded-full' : ''" :src="currentItem.url" />
|
|
||||||
</div>
|
|
||||||
<!-- 多图显示 -->
|
|
||||||
<a-space v-else-if="config.multiple && config.showList" :class="showImgList.length > 0 ? 'mr-2' : ''" wrap>
|
|
||||||
<div
|
<div
|
||||||
:class="'image-list ' + (config.rounded ? 'rounded-full' : '')"
|
:class="'image-list ' + (config.rounded ? 'rounded-full' : '')"
|
||||||
v-for="(image, idx) in showImgList"
|
v-if="!config.multiple && currentItem?.url && config.showList"
|
||||||
:key="idx"
|
|
||||||
>
|
>
|
||||||
<a-button class="delete" @click="removeImage(idx)">
|
<a-button class="delete" @click="removeSignImage()">
|
||||||
<template #icon><icon-delete /></template>
|
<template #icon>
|
||||||
|
<icon-delete />
|
||||||
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-image width="130" height="130" :class="config.rounded ? 'rounded-full' : ''" :src="image.url" />
|
<a-image
|
||||||
|
width="130"
|
||||||
|
height="130"
|
||||||
|
:class="config.rounded ? 'rounded-full' : ''"
|
||||||
|
:src="currentItem.url"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</a-space>
|
<!-- 多图显示 -->
|
||||||
|
<template v-else-if="config.multiple && config.showList">
|
||||||
<a-upload
|
<div
|
||||||
:custom-request="uploadImageHandler"
|
:class="'image-list ' + (config.rounded ? 'rounded-full' : '')"
|
||||||
:show-file-list="false"
|
v-for="(image, idx) in showImgList"
|
||||||
:multiple="config.multiple"
|
:key="idx"
|
||||||
:accept="config.accept ?? '.jpg,jpeg,.gif,.png,.svg,.bpm'"
|
>
|
||||||
:disabled="config.disabled"
|
<a-button class="delete" @click="removeImage(idx)">
|
||||||
:tip="config.tip"
|
<template #icon>
|
||||||
:limit="config.limit"
|
<icon-delete />
|
||||||
>
|
</template>
|
||||||
<template #upload-button>
|
</a-button>
|
||||||
<slot name="customer">
|
<a-image width="130" height="130" :class="config.rounded ? 'rounded-full' : ''" :src="image.url" />
|
||||||
<div
|
</div>
|
||||||
:class="'upload-skin ' + (config.rounded ? 'rounded-full' : 'rounded-sm')"
|
|
||||||
v-if="!props.modelValue || config.multiple"
|
|
||||||
>
|
|
||||||
<div class="icon text-3xl"><component :is="config.icon" /></div>
|
|
||||||
<div class="title">
|
|
||||||
{{ config.title === "buttonText" ? "本地上传" : config.title }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</slot>
|
|
||||||
</template>
|
</template>
|
||||||
</a-upload>
|
|
||||||
|
<a-upload
|
||||||
|
:custom-request="uploadImageHandler"
|
||||||
|
:show-file-list="false"
|
||||||
|
:multiple="config.multiple"
|
||||||
|
:accept="config.accept ?? '.jpg,jpeg,.gif,.png,.svg,.bpm'"
|
||||||
|
:disabled="config.disabled"
|
||||||
|
:tip="config.tip"
|
||||||
|
:limit="config.limit"
|
||||||
|
>
|
||||||
|
<template #upload-button>
|
||||||
|
<slot name="customer">
|
||||||
|
<div
|
||||||
|
:class="'upload-skin ' + (config.rounded ? 'rounded-full' : 'rounded-sm')"
|
||||||
|
v-if="!props.modelValue || config.multiple"
|
||||||
|
>
|
||||||
|
<div class="icon text-3xl">
|
||||||
|
<component :is="config.icon" />
|
||||||
|
</div>
|
||||||
|
<div class="title">
|
||||||
|
{{ config.title === "buttonText" ? $t("upload.buttonText") : config.title }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
|
</a-upload>
|
||||||
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, inject, watch } from "vue"
|
import { ref, inject, watch } from "vue"
|
||||||
import tool from "@/utils/tool"
|
import tool from "@/utils/tool"
|
||||||
import { isArray } from "lodash"
|
import { isArray, throttle } from "lodash-es"
|
||||||
import { getFileUrl, uploadRequest } from "../js/utils"
|
import { getFileUrl, uploadRequest } from "../js/utils"
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from "@arco-design/web-vue"
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: { type: [String, Number, Array], default: () => {} }
|
modelValue: {
|
||||||
|
type: [String, Number, Array],
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(["update:modelValue"])
|
const emit = defineEmits(["update:modelValue"])
|
||||||
const config = inject("config")
|
const config = inject("config")
|
||||||
@@ -73,7 +89,7 @@ const uploadImageHandler = async (options) => {
|
|||||||
}
|
}
|
||||||
const file = options.fileItem.file
|
const file = options.fileItem.file
|
||||||
if (file.size > config.size) {
|
if (file.size > config.size) {
|
||||||
Message.warning(file.name + " " + "文件大小超过了限制")
|
Message.warning(file.name + " " + t("upload.sizeLimit"))
|
||||||
currentItem.value = {}
|
currentItem.value = {}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -111,25 +127,40 @@ const removeImage = (idx) => {
|
|||||||
emit("update:modelValue", files)
|
emit("update:modelValue", files)
|
||||||
}
|
}
|
||||||
|
|
||||||
const init = async () => {
|
const init = throttle(async () => {
|
||||||
if (config.multiple) {
|
if (config.multiple) {
|
||||||
if (isArray(props.modelValue) && props.modelValue.length > 0) {
|
if (isArray(props.modelValue) && props.modelValue.length > 0) {
|
||||||
const result = await props.modelValue.map(async (item) => {
|
const result = await props.modelValue.map(async (item) => {
|
||||||
return await getFileUrl(config.returnType, item, storageMode)
|
return await getFileUrl(config.returnType, item, storageMode)
|
||||||
})
|
})
|
||||||
showImgList.value = await Promise.all(result)
|
const data = await Promise.all(result)
|
||||||
|
if (config.returnType === "url") {
|
||||||
|
showImgList.value = data.map((url) => {
|
||||||
|
return { url }
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
showImgList.value = data.map((item) => {
|
||||||
|
return { url: item.url, [config.returnType]: item[config.returnType] }
|
||||||
|
})
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
showImgList.value = []
|
showImgList.value = []
|
||||||
}
|
}
|
||||||
} else if (props.modelValue) {
|
} else if (props.modelValue) {
|
||||||
signImage.value = props.modelValue
|
if (config.returnType === "url") {
|
||||||
getFileUrl(config.returnType, props.modelValue, storageMode).then((item) => (currentItem.value.url = item))
|
signImage.value = props.modelValue
|
||||||
|
currentItem.value.url = props.modelValue
|
||||||
|
} else {
|
||||||
|
const result = await getFileUrl(config.returnType, props.modelValue, storageMode)
|
||||||
|
signImage.value = result.url
|
||||||
|
currentItem.value.url = result.url
|
||||||
|
}
|
||||||
currentItem.value.percent = 100
|
currentItem.value.percent = 100
|
||||||
currentItem.value.status = "complete"
|
currentItem.value.status = "complete"
|
||||||
} else {
|
} else {
|
||||||
removeSignImage()
|
removeSignImage()
|
||||||
}
|
}
|
||||||
}
|
}, 1000)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
@@ -153,6 +184,7 @@ watch(
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.icon,
|
.icon,
|
||||||
.title {
|
.title {
|
||||||
color: var(--color-text-3);
|
color: var(--color-text-3);
|
||||||
@@ -165,6 +197,7 @@ watch(
|
|||||||
background-color: var(--color-fill-2);
|
background-color: var(--color-fill-2);
|
||||||
width: 130px;
|
width: 130px;
|
||||||
height: 130px;
|
height: 130px;
|
||||||
|
|
||||||
.delete {
|
.delete {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
@@ -186,6 +219,7 @@ watch(
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-skin:hover {
|
.upload-skin:hover {
|
||||||
border: 1px dashed rgb(var(--primary-6));
|
border: 1px dashed rgb(var(--primary-6));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,63 +1,62 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<ma-image-upload v-if="props.type === 'image'" v-model="file" />
|
<ma-image-upload v-if="props.type === 'image'" v-model="file" />
|
||||||
<ma-file-upload v-if="props.type === 'file'" v-model="file" />
|
<ma-file-upload v-if="props.type === 'file'" v-model="file" />
|
||||||
<ma-chunk-upload v-if="props.type === 'chunk'" v-model="file" />
|
<ma-chunk-upload v-if="props.type === 'chunk'" v-model="file" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, provide } from "vue"
|
import { ref, watch, provide } from 'vue'
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from '@arco-design/web-vue'
|
||||||
|
|
||||||
import uploadConfig from "@/config/upload"
|
import uploadConfig from '@/config/upload'
|
||||||
import MaImageUpload from "./components/image-upload.vue"
|
import MaImageUpload from './components/image-upload.vue'
|
||||||
import MaFileUpload from "./components/file-upload.vue"
|
import MaFileUpload from './components/file-upload.vue'
|
||||||
import MaChunkUpload from "./components/chunk-upload.vue"
|
import MaChunkUpload from './components/chunk-upload.vue'
|
||||||
|
|
||||||
const emit = defineEmits(["update:modelValue"])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
const file = ref()
|
const file = ref()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: { type: [String, Number, Array], default: () => {} },
|
modelValue: { type: [ String, Number, Array ], default: () => {} },
|
||||||
title: { type: String, default: "buttonText" },
|
title: { type: String, default: 'buttonText', },
|
||||||
icon: { type: String, default: "icon-plus" },
|
icon: { type: String, default: 'icon-plus'},
|
||||||
rounded: { type: Boolean, default: false },
|
rounded: { type: Boolean, default: false },
|
||||||
multiple: { type: Boolean, default: false },
|
multiple: { type: Boolean, default: false },
|
||||||
disabled: { type: Boolean, default: false },
|
disabled: { type: Boolean, default: false },
|
||||||
draggable: { type: Boolean, default: false },
|
draggable: { type: Boolean, default: false },
|
||||||
size: { type: Number, default: 4 * 1024 * 1024 },
|
size: { type: Number, default: 4 * 1024 * 1024 },
|
||||||
chunk: { type: Boolean, default: false },
|
chunk: { type: Boolean, default: false },
|
||||||
chunkSize: { type: Number, default: 1 * 1024 * 1024 },
|
chunkSize: { type: Number, default: 1 * 1024 * 1024 },
|
||||||
limit: { type: Number, default: 0 },
|
limit: { type: Number, default: 0 },
|
||||||
tip: { type: String, default: undefined },
|
tip: { type: String, default: undefined },
|
||||||
type: { type: String, default: "image" },
|
type: { type: String, default: 'image' },
|
||||||
accept: { type: String, default: "*" },
|
accept: { type: String, default: '*' },
|
||||||
returnType: { type: String, default: "url" },
|
returnType: { type: String, default: 'hash' },
|
||||||
fileType: { type: String, default: "button" },
|
fileType: { type: String, default: 'button' },
|
||||||
showList: { type: Boolean, default: true },
|
showList: { type: Boolean, default: true },
|
||||||
requestData: { type: Object, default: {} }
|
requestData: { type: Object, default: {} },
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!["id", "url", "hash"].includes(props.returnType)) {
|
if (! ['id', 'url', 'hash'].includes(props.returnType)) {
|
||||||
Message.error("MaUpload组件props的returnType只能为:id, url, hash 其中一个")
|
Message.error('MaUpload组件props的returnType只能为:id, url, hash 其中一个')
|
||||||
console.error("MaUpload组件props的returnType只能为:id, url, hash 其中一个")
|
console.error('MaUpload组件props的returnType只能为:id, url, hash 其中一个')
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(() => props.modelValue, (val) => {
|
||||||
() => props.modelValue,
|
file.value = val
|
||||||
(val) => {
|
}, {
|
||||||
file.value = val
|
deep: true, immediate: true
|
||||||
},
|
})
|
||||||
{
|
|
||||||
deep: true,
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
provide("storageMode", uploadConfig.storageMode)
|
provide('storageMode', uploadConfig.storageMode)
|
||||||
provide("config", props)
|
provide('config', props)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => file.value,
|
() => file.value,
|
||||||
(vl) => emit("update:modelValue", vl)
|
vl => emit('update:modelValue', vl)
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,36 +1,36 @@
|
|||||||
import commonApi from "@/api/common"
|
import commonApi from '@/api/common'
|
||||||
import tool from "@/utils/tool"
|
import tool from '@/utils/tool'
|
||||||
import file2md5 from "file2md5"
|
import file2md5 from 'file2md5'
|
||||||
|
|
||||||
export const getFileUrl = async (returnType, value, storageMode) => {
|
export const getFileUrl = async (returnType, value, storageMode) => {
|
||||||
if (returnType === "url") {
|
if (returnType === 'url') {
|
||||||
return value
|
return value
|
||||||
} else if (returnType === "id") {
|
} else if (returnType === 'id') {
|
||||||
const { data } = await commonApi.getFileInfoById(value)
|
const { data } = await commonApi.getFileInfoById(value)
|
||||||
if (data) {
|
if (data) {
|
||||||
data.url = tool.attachUrl(data.url, storageMode[data.storage_mode])
|
data.url = tool.attachUrl(data.url, storageMode[data.storage_mode])
|
||||||
return data
|
return data
|
||||||
}
|
|
||||||
return ""
|
|
||||||
} else if (returnType === "hash") {
|
|
||||||
const { data } = await commonApi.getFileInfoByHash(value)
|
|
||||||
if (data) {
|
|
||||||
data.url = tool.attachUrl(data.url, storageMode[data.storage_mode])
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
return ''
|
||||||
|
} else if (returnType === 'hash') {
|
||||||
|
const { data } = await commonApi.getFileInfoByHash(value)
|
||||||
|
if (data) {
|
||||||
|
data.url = tool.attachUrl(data.url, storageMode[data.storage_mode])
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const uploadRequest = async (file, type, method, requestData = {}) => {
|
export const uploadRequest = async (file, type, method, requestData = {}) => {
|
||||||
const hash = await file2md5(file)
|
const hash = await file2md5(file)
|
||||||
const dataForm = new FormData()
|
const dataForm = new FormData()
|
||||||
dataForm.append(type, file)
|
dataForm.append(type, file)
|
||||||
dataForm.append("isChunk", false)
|
dataForm.append('isChunk', false)
|
||||||
dataForm.append("hash", hash)
|
dataForm.append('hash', hash)
|
||||||
for (let name in requestData) {
|
for (let name in requestData) {
|
||||||
dataForm.append(name, requestData[name])
|
dataForm.append(name, requestData[name])
|
||||||
}
|
}
|
||||||
const response = await commonApi[method](dataForm)
|
const response = await commonApi[method](dataForm)
|
||||||
return response.data
|
return response.data
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,133 +1,128 @@
|
|||||||
|
<!--
|
||||||
|
- @Author XXX
|
||||||
|
- @Link XXX
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="ma-content-block">
|
<div class="ma-content-block">
|
||||||
<a-space class="flex">
|
<a-space class="flex">
|
||||||
<a-button type="primary" @click="visible = true">
|
<a-button type="primary" @click="visible = true">
|
||||||
<template #icon><icon-select-all /></template>{{ props.text }}
|
<template #icon><icon-select-all /></template>{{ props.text }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-tag size="large" color="blue" v-if="props.isEcho"
|
<a-tag size="large" color="blue" v-if="props.isEcho">已选择 {{ isArray(selecteds) ? selecteds.length : 0 }} 位</a-tag>
|
||||||
>已选择 {{ isArray(selecteds) ? selecteds.length : 0 }} 位</a-tag
|
<a-input-tag v-model="userList" v-if="props.isEcho" :style="{ width:'320px' }" :placeholder="'请点击前面按钮' + props.text" :max-tag-count="3" disabled/>
|
||||||
>
|
</a-space>
|
||||||
<a-input-tag
|
|
||||||
v-model="userList"
|
|
||||||
v-if="props.isEcho"
|
|
||||||
:style="{ width: '320px' }"
|
|
||||||
:placeholder="'请点击前面按钮' + props.text"
|
|
||||||
:max-tag-count="3"
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
</a-space>
|
|
||||||
|
|
||||||
<a-modal v-model:visible="visible" width="1000px" draggable :on-before-ok="close" unmountOnClose>
|
<a-modal v-model:visible="visible" width="1000px" draggable :on-before-ok="close" unmountOnClose>
|
||||||
<template #title>{{ props.text }}</template>
|
<template #title>{{ props.text }}</template>
|
||||||
|
|
||||||
<ma-crud
|
<ma-crud
|
||||||
ref="crudRef"
|
ref="crudRef"
|
||||||
:options="crud"
|
:options="crud"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
v-model:selected-keys="selecteds"
|
v-model:selected-keys="selecteds"
|
||||||
@selection-change="selectHandler"
|
@selection-change="selectHandler"
|
||||||
/>
|
/>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref, watch } from "vue"
|
import { onMounted, ref, watch } from 'vue'
|
||||||
import commonApi from "@/api/common"
|
import commonApi from '@/api/common'
|
||||||
import { Message } from "@arco-design/web-vue"
|
import { Message } from '@arco-design/web-vue'
|
||||||
import { isArray, isEmpty } from "lodash"
|
import { isArray, isEmpty } from 'lodash'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: { type: Array },
|
modelValue: { type: Array },
|
||||||
isEcho: { type: Boolean, default: false },
|
isEcho: { type: Boolean, default: false },
|
||||||
multiple: { type: Boolean, default: true },
|
multiple: { type: Boolean, default: true },
|
||||||
onlyId: { type: Boolean, default: true },
|
onlyId: { type: Boolean, default: true },
|
||||||
text: { type: String, default: "选择用户" }
|
text: { type: String, default: '选择用户' }
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(["update:modelValue", "success"])
|
const emit = defineEmits(['update:modelValue', 'success'])
|
||||||
|
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const selecteds = ref([])
|
const selecteds = ref([])
|
||||||
const userList = ref([])
|
const userList = ref([])
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.isEcho && props.onlyId) selecteds.value = props.modelValue
|
if (props.isEcho && props.onlyId) selecteds.value = props.modelValue
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
(val) => {
|
val => {
|
||||||
if (props.isEcho && props.onlyId) selecteds.value = val
|
if (props.isEcho && props.onlyId) selecteds.value = val
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const selectHandler = (rows) => {
|
const selectHandler = (rows) => {
|
||||||
selecteds.value = rows
|
selecteds.value = rows
|
||||||
}
|
}
|
||||||
|
|
||||||
const close = async (done) => {
|
const close = async (done) => {
|
||||||
if (isArray(selecteds.value) && selecteds.value.length > 0) {
|
if (isArray(selecteds.value) && selecteds.value.length > 0) {
|
||||||
const response = await commonApi.getUserInfoByIds({ ids: selecteds.value })
|
const response = await commonApi.getUserInfoByIds({ ids: selecteds.value })
|
||||||
if (!isEmpty(response) && isArray(response.data)) {
|
if (! isEmpty(response) && isArray(response.data)) {
|
||||||
userList.value = response.data.map((item) => {
|
userList.value = response.data.map( item => {
|
||||||
return `${item.username}(${item.id})`
|
return `${item.username}(${item.id})`
|
||||||
})
|
})
|
||||||
if (props.onlyId) {
|
if (props.onlyId) {
|
||||||
emit("update:modelValue", selecteds.value)
|
emit('update:modelValue', selecteds.value)
|
||||||
} else {
|
} else {
|
||||||
emit("update:modelValue", response.data)
|
emit('update:modelValue', response.data)
|
||||||
}
|
|
||||||
emit("success", true)
|
|
||||||
Message.success("选择成功")
|
|
||||||
}
|
}
|
||||||
|
emit('success', true)
|
||||||
|
Message.success('选择成功')
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
emit("update:modelValue", [])
|
emit('update:modelValue', [])
|
||||||
userList.value = []
|
userList.value = []
|
||||||
}
|
}
|
||||||
done(true)
|
done(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
const crud = ref({
|
const crud = ref({
|
||||||
showIndex: false,
|
showIndex: false,
|
||||||
api: commonApi.getUserList,
|
api: commonApi.getUserList,
|
||||||
rowSelection: props.multiple ? { type: "checkbox", showCheckedAll: true } : { type: "radio" }
|
rowSelection: props.multiple ? { type: 'checkbox', showCheckedAll: true } : { type: 'radio' }
|
||||||
})
|
})
|
||||||
|
|
||||||
const columns = ref([
|
const columns = ref([
|
||||||
{ title: "账户", dataIndex: "username", search: true },
|
{ title: '账户', dataIndex: 'username', search: true },
|
||||||
{ title: "昵称", dataIndex: "nickname", search: true },
|
{ title: '昵称', dataIndex: 'nickname', search: true },
|
||||||
{ title: "手机", dataIndex: "phone", search: true },
|
{ title: '手机', dataIndex: 'phone', search: true },
|
||||||
{ title: "邮箱", dataIndex: "email", search: true },
|
{ title: '邮箱', dataIndex: 'email', search: true },
|
||||||
{
|
{
|
||||||
title: "部门",
|
title: '部门',
|
||||||
dataIndex: "dept_id",
|
dataIndex: 'dept_id',
|
||||||
search: true,
|
search: true,
|
||||||
formType: "tree-select",
|
formType: 'tree-select',
|
||||||
hide: true,
|
hide: true,
|
||||||
dict: { url: "system/common/getDeptTreeList" }
|
dict: { url: 'system/common/getDeptTreeList' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "角色",
|
title: '角色',
|
||||||
dataIndex: "role_id",
|
dataIndex: 'role_id',
|
||||||
search: true,
|
search: true,
|
||||||
formType: "select",
|
formType: 'select',
|
||||||
hide: true,
|
hide: true,
|
||||||
dict: { url: "system/common/getRoleList", props: { label: "name", value: "code" } }
|
dict: { url: 'system/common/getRoleList', props: { label: 'name', value: 'code' } }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "岗位",
|
title: '岗位',
|
||||||
dataIndex: "post_id",
|
dataIndex: 'post_id',
|
||||||
search: true,
|
search: true,
|
||||||
formType: "select",
|
formType: 'select',
|
||||||
hide: true,
|
hide: true,
|
||||||
dict: { url: "system/common/getPostList", props: { label: "name", value: "code" } }
|
dict: { url: 'system/common/getPostList', props: { label: 'name', value: 'code' } }
|
||||||
}
|
},
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
:deep(.arco-tabs-nav-type-capsule .arco-tabs-nav-tab) {
|
:deep(.arco-tabs-nav-type-capsule .arco-tabs-nav-tab) {
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,41 +1,37 @@
|
|||||||
<!--
|
<!--
|
||||||
- MineAdmin is committed to providing solutions for quickly building web applications
|
- @Author XXX
|
||||||
- Please view the LICENSE file that was distributed with this source code,
|
- @Link XXX
|
||||||
- For the full copyright and license information.
|
|
||||||
- Thank you very much for using MineAdmin.
|
|
||||||
-
|
|
||||||
- @Author X.Mo<root@imoi.cn>
|
|
||||||
- @Link https://gitee.com/xmo/mineadmin-vue
|
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-input v-model="val" :label="props.title" disabled class="w-full" />
|
<a-input v-model="val" :label="props.title" disabled class="w-full" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch } from "vue"
|
import { ref, watch } from 'vue'
|
||||||
import { useUserStore } from "@/store"
|
import { useUserStore } from '@/store'
|
||||||
|
|
||||||
const user = useUserStore().user
|
const user = useUserStore().user
|
||||||
const val = ref()
|
const val = ref()
|
||||||
|
|
||||||
const emit = defineEmits(["update:modelValue"])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: [String, Number],
|
modelValue: [ String, Number ],
|
||||||
title: { type: String, default: "用户信息" },
|
title: { type: String, default: '用户信息'},
|
||||||
field: { type: String, default: "id" }
|
field: { type: String, default: 'id'},
|
||||||
})
|
})
|
||||||
|
|
||||||
val.value = user[props.field] ? user[props.field].toString() : user.id.toString()
|
val.value = user[props.field] ? user[props.field].toString() : user.id.toString()
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => val.value,
|
() => val.value,
|
||||||
(vl) => emit("update:modelValue", vl),
|
vl => emit('update:modelValue', vl),
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
:deep(.arco-select-option-content) {
|
:deep(.arco-select-option-content) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user