Inline editor - Ext JS

本文探讨了在可滚动元素中精确定位的问题,并提出了一款演示工具以展示该问题。此外,还讨论了解决方案,即如何阻止ENTER和RETURN键默认提交表单的行为,以实现更好的用户体验。
This still has a slight problem positioning correctly over items in scrollable elements. That tree demo I posted [i]shouldi/i] exhibit this (My live menu builder does here), but those nodes aren't editable for some reason??????

Also, it should swallow the ENTER and RETRUN keypress events so that ending the edit with ENTER or RETURN doesn't submit the form the edit field has been placed in.
Reply With Quote
ERROR in ./node_modules/monaco-editor/esm/vs/base/browser/ui/codicons/codicon/codicon.css (./node_modules/monaco-editor/esm/vs/base/browser/ui/codicons/codicon/codicon.css.webpack[javascript/auto]!=!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-14.use[1]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-14.use[2]!./node_modules/monaco-editor/esm/vs/base/browser/ui/codicons/codicon/codicon.css) 5:36-77 Module not found: Error: Can't resolve './codicon.ttf' in 'E:\daima\DT\longdexunjian\front\node_modules\monaco-editor\esm\vs\base\browser\ui\codicons\codicon' @ ./node_modules/monaco-editor/esm/vs/base/browser/ui/codicons/codicon/codicon.css @ ./node_modules/monaco-editor/esm/vs/base/browser/ui/codicons/codiconStyles.js 5:0-31 @ ./node_modules/monaco-editor/esm/vs/editor/editor.all.js 64:0-54 @ ./node_modules/monaco-editor/esm/vs/editor/edcore.main.js 5:0-25 @ ./node_modules/monaco-editor/esm/vs/editor/editor.main.js 7:0-30 7:0-30 @ ./node_modules/@marsgis/editor/dist/editor.umd.js 1:78-102 @ ./src/main.js 49:14-40 ERROR in ./node_modules/monaco-editor/esm/vs/base/browser/ui/codicons/codicon/codicon.css Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js): HookWebpackError: Cannot find module './codicon.ttf' at tryRunOrWebpackError (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\HookWebpackError.js:86:9) at __webpack_require_module__ (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5464:12) at __webpack_require__ (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5411:18) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5498:20 at symbolIterator (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3485:9) at done (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3527:9) at Hook.eval [as callAsync] (eval at create (E:\daima\DT\longdexunjian\front\node_modules\webpack\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:15:1) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5386:43 at symbolIterator (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3482:9) at timesSync (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:2297:7) at Object.eachLimit (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3463:5) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5348:16 at symbolIterator (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3485:9) at done (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3527:9) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5262:8 at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:3680:5 at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Cache.js:99:5 at Hook.eval [as callAsync] (eval at create (E:\daima\DT\longdexunjian\front\node_modules\webpack\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:16:1) at Cache.get (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Cache.js:81:18) at ItemCacheFacade.get (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\CacheFacade.js:116:15) at Compilation._codeGenerationModule (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:3644:9) at codeGen (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5250:11) at symbolIterator (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3482:9) at timesSync (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:2297:7) at Object.eachLimit (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3463:5) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5316:15 at symbolIterator (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3485:9) at timesSync (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:2297:7) at Object.eachLimit (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3463:5) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5280:14 at processQueue (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\util\processAsyncTree.js:61:4) at process.processTicksAndRejections (node:internal/process/task_queues:85:11) -- inner error -- Error: Cannot find module './codicon.ttf' at webpackMissingModule (E:\daima\DT\longdexunjian\front\node_modules\css-loader\dist\cjs.js??clonedRuleSet-14.use[1]!E:\daima\DT\longdexunjian\front\node_modules\postcss-loader\dist\cjs.js??clonedRuleSet-14.use[2]!E:\daima\DT\longdexunjian\front\node_modules\monaco-editor\esm\vs\base\browser\ui\codicons\codicon\codicon.css:12:113) at Module.<anonymous> (E:\daima\DT\longdexunjian\front\node_modules\css-loader\dist\cjs.js??clonedRuleSet-14.use[1]!E:\daima\DT\longdexunjian\front\node_modules\postcss-loader\dist\cjs.js??clonedRuleSet-14.use[2]!E:\daima\DT\longdexunjian\front\node_modules\monaco-editor\esm\vs\base\browser\ui\codicons\codicon\codicon.css:12:201) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\javascript\JavascriptModulesPlugin.js:518:10 at Hook.eval [as call] (eval at create (E:\daima\DT\longdexunjian\front\node_modules\webpack\node_modules\tapable\lib\HookCodeFactory.js:19:10), <anonymous>:7:1) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5466:39 at tryRunOrWebpackError (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\HookWebpackError.js:81:7) at __webpack_require_module__ (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5464:12) at __webpack_require__ (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5411:18) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5498:20 at symbolIterator (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3485:9) at done (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3527:9) at Hook.eval [as callAsync] (eval at create (E:\daima\DT\longdexunjian\front\node_modules\webpack\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:15:1) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5386:43 at symbolIterator (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3482:9) at timesSync (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:2297:7) at Object.eachLimit (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3463:5) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5348:16 at symbolIterator (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3485:9) at done (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3527:9) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5262:8 at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:3680:5 at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Cache.js:99:5 at Hook.eval [as callAsync] (eval at create (E:\daima\DT\longdexunjian\front\node_modules\webpack\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:16:1) at Cache.get (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Cache.js:81:18) at ItemCacheFacade.get (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\CacheFacade.js:116:15) at Compilation._codeGenerationModule (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:3644:9) at codeGen (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5250:11) at symbolIterator (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3482:9) at timesSync (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:2297:7) at Object.eachLimit (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3463:5) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5316:15 at symbolIterator (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3485:9) at timesSync (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:2297:7) at Object.eachLimit (E:\daima\DT\longdexunjian\front\node_modules\neo-async\async.js:3463:5) at E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\Compilation.js:5280:14 at processQueue (E:\daima\DT\longdexunjian\front\node_modules\webpack\lib\util\processAsyncTree.js:61:4) at process.processTicksAndRejections (node:internal/process/task_queues:85:11) Generated code for E:\daima\DT\longdexunjian\front\node_modules\css-loader\dist\cjs.js??clonedRuleSet-14.use[1]!E:\daima\DT\longdexunjian\front\node_modules\postcss-loader\dist\cjs.js??clonedRuleSet-14.use[2]!E:\daima\DT\longdexunjian\front\node_modules\monaco-editor\esm\vs\base\browser\ui\codicons\codicon\codicon.css 1 | __webpack_require__.r(__webpack_exports__); 2 | /* harmony import */ var _css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../../../../css-loader/dist/runtime/noSourceMaps.js */ "E:\\daima\\DT\\longdexunjian\\front\\node_modules\\css-loader\\dist\\runtime\\noSourceMaps.js"); 3 | /* harmony import */ var _css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__); 4 | /* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../../../../css-loader/dist/runtime/api.js */ "E:\\daima\\DT\\longdexunjian\\front\\node_modules\\css-loader\\dist\\runtime\\api.js"); 5 | /* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); 6 | /* harmony import */ var _css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../../../../../../css-loader/dist/runtime/getUrl.js */ "E:\\daima\\DT\\longdexunjian\\front\\node_modules\\css-loader\\dist\\runtime\\getUrl.js"); 7 | /* harmony import */ var _css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2__); 8 | // Imports 9 | 10 | 11 | 12 | var ___CSS_LOADER_URL_IMPORT_0___ = new URL(/* asset import */ Object(function webpackMissingModule() { var e = new Error("Cannot find module './codicon.ttf'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()), __webpack_require__.b); 13 | var ___CSS_LOADER_EXPORT___ = _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); 14 | var ___CSS_LOADER_URL_REPLACEMENT_0___ = _css_loader_dist_runtime_getUrl_js__WEBPACK_IMPORTED_MODULE_2___default()(___CSS_LOADER_URL_IMPORT_0___); 15 | // Module 16 | ___CSS_LOADER_EXPORT___.push([module.id, "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. S ee License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\n@font-face {\n\tfont-family: \"codicon\";\n\tfont-display: block;\n\tsrc: url(" + _ __CSS_LOADER_URL_REPLACEMENT_0___ + ") format(\"truetype\");\n}\n\n.codicon[class*='codicon-'] {\n\tfont: normal normal normal 16px/1 codicon;\n\tdisplay: inline-block;\n\ttext-decoration: none;\n\ttext-rendering: auto;\n\ttext-align: center;\n \ttext-transform: none;\n\t-webkit-font-smoothing: antialiased;\n\t-moz-osx-font-smoothing: grayscale;\n\t-moz-user-select: none;\n\t -ms-user-select: none;\n\t user-select: none;\n\t-webkit-user-select: none;\n}\n\n/* icon rules are dynamically created by the platform theme service (see iconsStyleSheet.ts) */\n", ""]); 17 | // Exports 18 | /* harmony default export */ __webpack_exports__["default"] = (___CSS_LOADER_EXPORT___); 19 | @ ./node_modules/monaco-editor/esm/vs/base/browser/ui/codicons/codiconStyles.js 5:0-31 @ ./node_modules/monaco-editor/esm/vs/editor/editor.all.js 64:0-54 @ ./node_modules/monaco-editor/esm/vs/editor/edcore.main.js 5:0-25 @ ./node_modules/monaco-editor/esm/vs/editor/editor.main.js 7:0-30 7:0-30 @ ./node_modules/@marsgis/editor/dist/editor.umd.js 1:78-102 @ ./src/main.js 49:14-40 巡检业务管理平台 compiled with 2 errors
07-02
{ "name": "admin", "version": "1.2.8", "description": "eapAdmin", "author": "shan", "email": "595485548@qq.com", "private": true, "scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "start": "npm run dev", "unit": "jest --config test/unit/jest.conf.js --coverage", "e2e": "node test/e2e/runner.js", "test": "npm run unit && npm run e2e", "lint": "eslint --ext .js,.vue src test/unit test/e2e/specs", "build": "node build/build.js", "analyz": "cross-env NODE_ENV=production npm_config_report=true npm run build", "startdll": "webpack --config build/webpack.dll.config.js" }, "dependencies": { "@jiaminghi/data-view": "^2.10.0", "ant-design-vue": "^1.7.2", "axios": "^0.19.2", "crypto-js": "^4.1.1", "dayjs": "^1.11.3", "echarts": "^4.1.0", "element-resize-detector": "^1.2.4", "element-ui": "^2.13.1", "file-save": "^0.2.0", "file-saver": "^2.0.5", "font-awesome": "^4.7.0", "js-cookie": "^2.2.0", "js-md5": "^0.7.3", "jsencrypt": "^3.3.2", "module": "^1.2.5", "moment": "^2.29.4", "nprogress": "^0.2.0", "pinyin": "^2.10.2", "screenfull": "^3.3.3", "scriptjs": "^2.5.8", "shortid": "^2.2.15", "sortablejs": "^1.7.0", "vue": "^2.5.2", "vue-i18n": "^8.4.0", "vue-quill-editor": "^3.0.6", "vue-router": "^3.0.1", "vue-svgicon": "^3.2.9", "vuex": "^3.0.1", "wangeditor": "^3.1.1", "xlsx": "^0.17.0" }, "devDependencies": { "ajv": "^5.5.2", "autoprefixer": "^7.1.2", "babel-core": "^6.22.1", "babel-eslint": "^8.2.1", "babel-helper-vue-jsx-merge-props": "^2.0.3", "babel-jest": "^21.0.2", "babel-loader": "^7.1.1", "babel-plugin-dynamic-import-node": "^1.2.0", "babel-plugin-syntax-jsx": "^6.18.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", "babel-plugin-transform-runtime": "^6.22.0", "babel-plugin-transform-vue-jsx": "^3.5.0", "babel-preset-env": "^1.3.2", "babel-preset-stage-2": "^6.22.0", "babel-register": "^6.22.0", "browserslist": "^4.25.1", "cache-loader": "^4.1.0", "chalk": "^2.0.1", "chromedriver": "^2.27.2", "compression-webpack-plugin": "^3.1.0", "copy-webpack-plugin": "^4.0.1", "cross-env": "^6.0.3", "cross-spawn": "^5.0.1", "css-loader": "^3.5.2", "eslint": "^7.32.0", "eslint-config-standard": "^10.2.1", "eslint-friendly-formatter": "^3.0.0", "eslint-loader": "^4.0.0", "eslint-plugin-import": "^2.32.0", "eslint-plugin-node": "^5.2.1", "eslint-plugin-promise": "^3.4.0", "eslint-plugin-standard": "^3.0.1", "eslint-plugin-vue": "^4.0.0", "extract-text-webpack-plugin": "^3.0.0", "file-loader": "^3.0.1", "friendly-errors-webpack-plugin": "^1.6.1", "gulp": "^3.9.1", "hard-source-webpack-plugin": "^0.13.1", "html-webpack-plugin": "^4.2.0", "jest": "^22.0.4", "jest-serializer-vue": "^0.3.0", "less": "^3.10.3", "less-loader": "^5.0.0", "mini-css-extract-plugin": "^0.9.0", "nightwatch": "^0.9.12", "node-notifier": "^5.1.2", "optimize-css-assets-webpack-plugin": "^3.2.0", "ora": "^1.2.0", "portfinder": "^1.0.13", "postcss-import": "^12.0.1", "postcss-loader": "^3.0.0", "postcss-url": "^7.2.1", "rimraf": "^2.6.0", "sass-loader": "^7.1.0", "script-loader": "^0.7.2", "selenium-server": "^3.0.1", "semver": "^5.3.0", "shelljs": "^0.7.6", "style-loader": "^1.1.4", "svg-sprite-loader": "^6.0.11", "thread-loader": "^2.1.3", "uglifyjs-webpack-plugin": "^2.2.0", "url-loader": "^4.1.0", "vue-jest": "^1.0.2", "vue-loader": "^15.9.1", "vue-style-loader": "^3.0.1", "vue-template-compiler": "^2.5.2", "webpack": "^4.47.0", "webpack-bundle-analyzer": "^2.9.0", "webpack-cli": "^3.3.11", "webpack-dev-server": "^3.10.3", "webpack-merge": "^4.1.0" }, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" }, "browserslist": [ "> 1%", "last 2 versions", "not ie <= 8" ] } 这是我的package.json
07-11
<template> <el-dialog :visible.sync="dialogVisible" :title="`${title[operateType]}范围子规则`" width="500" :close-on-click-modal="false" > <el-form :model="ruleForm" :rules="rules" ref="ruleFormRef" label-width="100px" class="base-ruleForm" label-position="top" size="mini" :disabled="operateType == 'detail'" > <el-form-item label="规则名称" prop="nameCn"> <el-input v-model="ruleForm.nameCn"></el-input> </el-form-item> <el-form-item label="描述" prop="description"> <el-input v-model="ruleForm.description" type="textarea" rows="3" show-word-limit maxlength="200" ></el-input> </el-form-item> </el-form> <el-form :model="customRuleForm" :rules="customRules" :inline="true" ref="customRuleFormRef" label-width="100px" class="custom-ruleForm" label-position="top" size="mini" :disabled="operateType == 'detail'" > <el-form-item label="发送人类型" prop="fromTypeList"> <el-select v-model="customRuleForm.fromTypeList" multiple @change="dealSelectAll('fromTypeList')" > <el-option v-for="opt in filterOptions.FromTypeEnum" :key="opt.code" :label="opt.info" :value="opt.code" > </el-option> </el-select> </el-form-item> <el-form-item label="接收人类型" prop="toTypeList"> <el-select v-model="customRuleForm.toTypeList" multiple @change="dealSelectAll('toTypeList')" > <el-option v-for="opt in filterOptions.ToTypeEnum" :key="opt.code" :label="opt.info" :value="opt.code" > </el-option> </el-select> </el-form-item> <el-form-item label="消息类型" prop="msgTypeList"> <el-select v-model="customRuleForm.msgTypeList" multiple> <el-option v-for="opt in filterOptions.MsgTypeEnum" :key="opt.code" :label="opt.info" :value="opt.code" > </el-option> </el-select> </el-form-item> <el-form-item label="聊天类型" prop="chatTypeList"> <el-select v-model="customRuleForm.chatTypeList" multiple @change="changeChatTypeList(false)" > <el-option v-for="opt in filterOptions.ChatTypeEnum" :key="opt.code" :label="opt.info" :value="opt.code" > </el-option> </el-select> </el-form-item> <el-form-item label="群聊群主" prop="roomOwnerIdList"> <el-select v-model="customRuleForm.roomOwnerIdList" multiple> <el-option v-for="opt in filterOptions.RoomOwnerIdListEnum" :key="opt.ownerId" :label="opt.ownerName" :value="opt.ownerId" > </el-option> </el-select> </el-form-item> <el-form-item label="群主员工所属部门" prop="roomOwnerDeptList"> <el-select v-model="customRuleForm.roomOwnerDeptList" multiple filterable remote :remote-method="searchDepts" :loading="roomOwnerDeptScroll.loading" v-infinite-scroll="loadMoreDepts" infinite-scroll-disabled="roomOwnerDeptScroll.loading" infinite-scroll-distance="50" > <el-option v-for="opt in filterOptions.RoomOwnerDeptListEnum" :key="opt.id" :label="opt.name" :value="opt.id" > </el-option> <div v-if="roomOwnerDeptScroll.loading" class="loading-text"> 加载中... </div> <div v-if="!roomOwnerDeptScroll.noMore" class="loading-text"> 下拉加载更多... </div> <div v-if="roomOwnerDeptScroll.noMore" class="loading-text"> 没有更多了 </div> </el-select> </el-form-item> <el-form-item label="群聊列表" prop="roomIdList"> <el-select v-model="customRuleForm.roomIdList" multiple @change="changeRoomId(false)" > <el-option v-for="opt in filterOptions.RoomIdListEnum" :key="opt.roomId" :label="opt.roomName" :value="opt.roomId" > </el-option> </el-select> </el-form-item> <el-form-item label="群聊成员白名单" prop="roomExcludeList"> <el-select v-model="customRuleForm.roomExcludeList" multiple> <el-option v-for="opt in filterOptions.roomExcludeListEnum" :key="opt.qwUserId" :label="opt.name" :value="opt.qwUserId" > </el-option> </el-select> </el-form-item> <el-form-item label="群聊关注成员" prop="roomFocueList"> <el-select v-model="customRuleForm.roomFocueList" multiple> <el-option v-for="opt in filterOptions.roomExcludeListEnum" :key="opt.qwUserId" :label="opt.name" :value="opt.qwUserId" > </el-option> </el-select> </el-form-item> <el-form-item label="员工" prop="employeeList"> <private-cloud-member-select-new style="width: 100%" ref="privateCloudMemberUse" placeholder="请选择员工" :defaultCheckedKey="defalutValue.employeeList" mode="member" @selectedMembers="choseEmployeeList" /> </el-form-item> <el-form-item label="部门" prop="deptList"> <private-cloud-member-select-new style="width: 100%" ref="privateCloudDeptUse" mode="group" placeholder="请选择部门" :defaultCheckedKey="defalutValue.deptList" @selectedGroups="choseDeptList" /> </el-form-item> <el-form-item label="是否启用白名单" prop="enableWhite"> <el-switch v-model="customRuleForm.enableWhite" :active-value="1" :inactive-value="0" > </el-switch> </el-form-item> <el-form-item label="正则表达式" prop="textRegex" style="width: 100%"> <vue-json-editor v-model="customRuleForm.textRegex" style="width: 100%" mode="code" lang="zh" ></vue-json-editor> </el-form-item> </el-form> <div class="el-form-item el-form--label-top" style="margin-bottom: 0"> <label for="" class="el-form-item__label">扩展信息</label> <div class="el-form-item__content extra-info"> <vue-json-editor ref="jsonRef" v-model="ext" style="width: 100%" mode="code" lang="zh" ></vue-json-editor> </div> </div> <div slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取消</el-button> <el-button type="primary" @click="save" :disabled="operateType == 'detail'" > 确定 </el-button> </div> </el-dialog> </template> <script> import vueJsonEditor from 'vue-json-editor' import archivesApi from '@/api/archive/index' import dayjs from 'dayjs' import { debounce } from 'lodash' export default { components: { vueJsonEditor, }, props: { type: String, }, data() { return { dialogVisible: false, ruleForm: { nameCn: '', description: '', }, rules: { nameCn: [ { required: true, message: '请输入活动名称', trigger: 'blur' }, { max: 20, message: '长度不能超过20个字符', trigger: 'blur' }, ], }, formConfig: [], customRuleForm: { fromTypeList: null, toTypeList: null, msgTypeList: null, chatTypeList: null, roomOwnerIdList: null, roomOwnerDeptList: null, roomIdList: null, roomExcludeList: null, roomFocueList: null, employeeList: null, deptList: null, enableWhite: 0, textRegex: {}, }, filterOptions: {}, customRules: {}, ext: {}, hasJsonErrorFlag: false, defalutValue: { employeeList: [], deptList: [], }, isEdit: false, operateType: null, editIndex: null, groupData: [], title: { add: '添加', edit: '编辑', detail: '查看', }, roomOwnerDeptScroll: { page: 1, pageSize: 20, loading: false, noMore: false, keyword: '', total: 0, }, } }, watch: { dialogVisible(newVal) { if (!newVal) { this.resetFiled() } }, }, mounted() {}, methods: { // 获取筛选项 async getFilter(filter, ruleType, row = null, index) { this.operateType = ruleType this.isEdit = ruleType === 'edit' ? true : false if (this.isEdit) { this.editIndex = index } this.filterOptions = { ...filter } this.resetScrollData() await this.getRoomList(true) await this.getOwnerDeptList(true) if (ruleType === 'add' && row) { this.$set(this.ruleForm, 'nameCn', row.nameCn) } else if (row) { this.$set(this.ruleForm, 'nameCn', row.nameCn) this.$set(this.ruleForm, 'description', row.description) this.customRuleForm = { ...row } this.customRuleForm.textRegex = JSON.parse(row.textRegex) if (row.ext) { this.ext = JSON.parse(row.ext) } this.defalutValue.employeeList = row.employeeListIds?.map( (item) => `_${item}` || [] ) this.defalutValue.deptList = row.deptList ? [...row.deptList] : [] await this.changeChatTypeList(true) await this.changeRoomId(true) if (row.roomOwnerDeptList) { await this.handleMissingDepts(row.roomOwnerDeptList) } } }, dealSelectAll(type) { if (this.customRuleForm[type]?.includes(0)) { this.customRuleForm[type] = [0] } }, // 获取群主列表或者群聊列表 async getRoomList(isEditInit) { await archivesApi .getRoomList({}) .then((res) => { if (res.data.success) { const data = res.data.data this.groupData = [...data] this.changeChatTypeList(isEditInit) } else { this.$message.error(res.data.msg || '获取失败') } }) .catch(() => {}) }, // 选择群聊类型时 changeChatTypeList(isEditInit = false) { console.log('群聊类型isEditInit', isEditInit) if (this.customRuleForm.chatTypeList?.includes(0)) { this.$set(this.customRuleForm, 'chatTypeList', [0]) } if ( this.customRuleForm.chatTypeList.includes(0) || this.customRuleForm.chatTypeList == null ) { this.filterOptions.RoomOwnerIdListEnum = this.groupData.reduce( (acc, item) => { if (!acc.some((i) => i.ownerId === item.ownerId)) { acc.push(item) } return acc }, [] ) this.filterOptions.RoomIdListEnum = this.groupData.reduce( (acc, item) => { if (!acc.some((i) => i.roomId === item.roomId)) { acc.push(item) } return acc }, [] ) } else { this.filterOptions.RoomOwnerIdListEnum = this.groupData .filter((item) => this.customRuleForm.chatTypeList?.includes(item.chatType) ) .reduce((acc, item) => { if (!acc.some((i) => i.ownerId === item.ownerId)) { acc.push(item) } return acc }, []) this.filterOptions.RoomIdListEnum = this.groupData .filter((item) => this.customRuleForm.chatTypeList?.includes(item.chatType) ) .reduce((acc, item) => { if (!acc.some((i) => i.roomId === item.roomId)) { acc.push(item) } return acc }, []) } if (!isEditInit) { this.customRuleForm.roomOwnerIdList = [] this.customRuleForm.roomIdList = [] this.customRuleForm.roomExcludeList = [] this.customRuleForm.roomFocueList = [] } }, // 选择群列表 async changeRoomId(isEditInit = false) { if (this.customRuleForm.roomIdList?.length) { const params = { roomIds: this.customRuleForm.roomIdList, } await archivesApi .getRoomMemberList(params) .then((res) => { if (res.data.success) { const data = res.data.data this.$set(this.filterOptions, 'roomExcludeListEnum', data) this.filterOptions.roomExcludeListEnum = this.filterOptions.roomExcludeListEnum.reduce((acc, item) => { if (!acc.some((i) => i.qwUserId === item.qwUserId)) { acc.push(item) } return acc }, []) } else { this.filterOptions.roomExcludeListEnum = [] this.$message.error(res.data.msg || '获取失败') } }) .catch(() => {}) console.log('群列表isEditInit', isEditInit) if (!isEditInit) { this.customRuleForm.roomExcludeList = [] this.customRuleForm.roomFocueList = [] } } else { this.filterOptions.roomExcludeListEnum = [] } }, // 获取群主部门 async getOwnerDeptList(init = false) { if (this.roomOwnerDeptScroll.loading) return this.roomOwnerDeptScroll.loading = true if (init) { this.roomOwnerDeptScroll.page = 1 this.filterOptions.RoomOwnerDeptListEnum = [] this.roomOwnerDeptScroll.noMore = false } await archivesApi .getOwnerDeptList({}) .then((res) => { console.log('res', res) if (res.data.success) { const data = res.data.data this.$set(this.filterOptions, 'RoomOwnerDeptListEnum', data) this.roomOwnerDeptScroll.loading = false this.roomOwnerDeptScroll.noMore = false } else { this.$message.error(res.data.msg || '获取失败') } }) .catch(() => {}) }, // 加载更多部门(滚动触发) loadMoreDepts: debounce(function () { console.log('加载更多部门') if ( !this.roomOwnerDeptScroll.loading && !this.roomOwnerDeptScroll.noMore ) { this.roomOwnerDeptScroll.page++ this.getOwnerDeptList() } }, 300), // 部门搜索 searchDepts: debounce(function (query) { this.roomOwnerDeptScroll.keyword = query this.roomOwnerDeptScroll.page = 1 this.getOwnerDeptList(true) }, 500), // 处理编辑时缺失的部门选项(回显) async handleMissingDepts(deptIds) { // 找出当前不在列表中的部门ID const missingIds = deptIds.filter( (id) => !this.filterOptions.RoomOwnerDeptListEnum.some((opt) => opt.id === id) ) // if (missingIds.length > 0) { // try { // const res = await archivesApi.getDeptsByIds({ ids: missingIds }) // if (res.data.success) { // // 将缺失的部门添加到列表开头 // this.deptOptions = [...res.data.data, ...this.deptOptions] // } // } catch (e) { // console.error('加载缺失部门失败', e) // } // } }, // 重置滚动加载相关数据 resetScrollData() { // 部门下拉框 this.filterOptions.RoomOwnerDeptListEnum = [] this.roomOwnerDeptScroll = { page: 1, pageSize: 20, loading: false, noMore: false, keyword: '', total: 0, } }, save() { let isPass = true this.$refs.ruleFormRef.validate((valid) => { if (!valid) { isPass = false } }) this.$refs.customRuleFormRef.validate((valid) => { if (!valid) { isPass = false } }) console.log('筛选项验证通过', this.ext) if (this.$refs.jsonRef.error) { isPass = false this.$message.error('扩展信息JSON格式错误') return } if (!isPass) { return } const params = { ...this.customRuleForm, ...this.ruleForm, textRegex: JSON.stringify(this.customRuleForm.textRegex), ext: JSON.stringify(this.ext), } if (this.isEdit) { params.gmtModified = dayjs().format('YYYY-MM-DD HH:mm:ss') this.$emit('freshData', params, this.type, this.editIndex) } else { params.gmtCreate = dayjs().format('YYYY-MM-DD HH:mm:ss') this.$emit('freshData', params, this.type) } this.resetFiled() this.dialogVisible = false console.log(isPass, 'isPass') }, // 选择员工 choseEmployeeList(val) { const { empList = [] } = val || {} let checkedKey = [] let checkedEmployee = [] let checkedEmployeeIds = [] if (empList && empList.length) { // 回显使用成员id checkedKey = checkedKey.concat(empList.map((x) => `_${x.id}`)) checkedEmployee = checkedEmployee.concat(empList.map((x) => x.qwUserId)) checkedEmployeeIds = checkedEmployeeIds.concat(empList.map((x) => x.id)) } this.defalutValue.employeeList = checkedKey this.customRuleForm.employeeList = checkedEmployee this.customRuleForm.employeeListIds = checkedEmployeeIds }, // 选择部门 choseDeptList(val) { const { deptList = [] } = val || {} let checkedKey = [] // 员工回显 if (deptList && deptList.length) { checkedKey = deptList.map((x) => x.nodeId) } this.defalutValue.deptList = checkedKey this.customRuleForm.deptList = checkedKey }, resetFiled() { this.ruleForm = { nameCn: '', description: '', } this.customRuleForm = { fromTypeList: null, toTypeList: null, msgTypeList: null, chatTypeList: null, roomOwnerIdList: null, roomOwnerDeptList: null, roomIdList: null, roomExcludeList: null, roomFocueList: null, employeeList: null, deptList: null, enableWhite: 0, textRegex: {}, employeeListIds: null, } this.defalutValue = { employeeList: [], deptList: [], } this.$refs.privateCloudMemberUse.reset() this.$refs.privateCloudDeptUse.reset() this.$refs.ruleFormRef.resetFields() this.$refs.customRuleFormRef.resetFields() this.ext = {} }, }, } </script> <style lang="scss" scoped> ::v-deep .el-form-item__label { line-height: 1; } .dialog-footer { display: flex; justify-content: flex-end; } .extra-info { display: flex; margin-bottom: 10px; .delete-icon { margin-left: 10px; } } ::v-deep .el-dialog { height: auto; margin-top: 8vh; .el-dialog__body { height: 60vh; overflow: auto; } } .custom-ruleForm { .el-form-item { width: 30%; .el-select { width: 100%; } } } ::v-deep a.jsoneditor-poweredBy { display: none; } .loading-text { padding: 4px 0; text-align: center; color: #999; font-size: 12px; } </style> el-select v-infinite-scroll不生效
10-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值