You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

314 lines
6.9 KiB

7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
  1. <template>
  2. <el-dialog
  3. title="数据源选择"
  4. :visible="visible"
  5. :close-on-click-modal="false"
  6. width="800px"
  7. top="5vh"
  8. custom-class="data-source-dialog"
  9. @close="handleClose"
  10. >
  11. <div class="data-source-content">
  12. <el-form label-position="top">
  13. <el-form-item label="可用数据字段">
  14. <el-checkbox-group v-model="selectedKeys" class="checkbox-grid">
  15. <el-checkbox
  16. v-for="key in dataKeys"
  17. :key="key.fieldName"
  18. :label="key.fieldName"
  19. class="checkbox-item"
  20. >
  21. {{ key.fieldName+(key.fieldDescription?('('+key.fieldDescription +')'):'')}}
  22. </el-checkbox>
  23. </el-checkbox-group>
  24. </el-form-item>
  25. </el-form>
  26. </div>
  27. <div slot="footer" class="dialog-footer">
  28. <el-button @click="handleClose">取消</el-button>
  29. <el-button type="primary" @click="handleConfirm">确定</el-button>
  30. </div>
  31. </el-dialog>
  32. </template>
  33. <script>
  34. export default {
  35. name: 'DataSourceDialog',
  36. props: {
  37. visible: Boolean,
  38. dataKeys: {
  39. type: Array,
  40. default: () => []
  41. },
  42. // 当前文本内容,用于分析应该勾选哪些数据字段
  43. currentText: {
  44. type: String,
  45. default: ''
  46. },
  47. sourceType: {
  48. type: String,
  49. default: 'text' // 默认是文本类型
  50. }
  51. },
  52. emits: ['update:visible', 'confirm'],
  53. data() {
  54. return {
  55. selectedKeys: []
  56. }
  57. },
  58. watch: {
  59. visible(newVal) {
  60. if (newVal) {
  61. this.initializeSelection()
  62. }
  63. }
  64. },
  65. methods: {
  66. // 根据当前文本内容初始化选择状态
  67. initializeSelection() {
  68. if (!this.currentText || !this.dataKeys.length) {
  69. this.selectedKeys = []
  70. return
  71. }
  72. // 分析文本内容,找出其中包含的数据字段
  73. const foundKeys = []
  74. this.dataKeys.forEach(key => {
  75. // 检查文本中是否包含 #{key} 格式的数据字段
  76. const pattern = new RegExp(`#\\{${key.fieldName}\\}`, 'g')
  77. if (pattern.test(this.currentText)) {
  78. foundKeys.push(key.fieldName)
  79. }
  80. })
  81. this.selectedKeys = foundKeys
  82. },
  83. handleClose() {
  84. this.$emit('update:visible', false)
  85. },
  86. handleConfirm() {
  87. this.$emit('confirm', this.selectedKeys, this.sourceType)
  88. this.handleClose()
  89. }
  90. }
  91. }
  92. </script>
  93. <style scoped>
  94. .data-source-dialog {
  95. max-width: 98vw !important;
  96. max-height: 92vh !important;
  97. border-radius: 12px !important;
  98. box-shadow: 0 12px 32px rgba(0,0,0,0.15) !important;
  99. background: #fff !important;
  100. }
  101. .data-source-dialog .el-dialog__header {
  102. padding: 16px 20px 8px !important;
  103. border-bottom: 1px solid #e4e7ed !important;
  104. background: #fff !important;
  105. }
  106. .data-source-dialog .el-dialog__title {
  107. font-size: 20px !important;
  108. font-weight: 700 !important;
  109. color: #222 !important;
  110. }
  111. .data-source-dialog .el-dialog__body {
  112. padding: 10px 20px 0 20px !important;
  113. max-height: 70vh !important;
  114. min-height: 80px;
  115. overflow-y: auto !important;
  116. background: #fff !important;
  117. }
  118. .data-source-content {
  119. width: 100%;
  120. min-height: 60px;
  121. }
  122. /* 表单项样式优化 */
  123. .el-form-item {
  124. margin-bottom: 12px;
  125. }
  126. .el-form-item:last-child {
  127. margin-bottom: 0;
  128. }
  129. .el-form-item__label {
  130. font-size: 14px !important;
  131. font-weight: 600 !important;
  132. color: #303133 !important;
  133. padding-bottom: 8px !important;
  134. line-height: 1.4 !important;
  135. }
  136. /* 复选框网格布局 */
  137. .checkbox-grid {
  138. display: grid;
  139. grid-template-columns: repeat(4, 1fr); /* 固定一行4个 */
  140. gap: 8px 10px;
  141. margin-top: 6px;
  142. padding: 0;
  143. background: none;
  144. border: none;
  145. border-radius: 0;
  146. /* 让复选框区域高度自适应内容 */
  147. max-height: none;
  148. overflow-y: visible;
  149. min-height: 80px;
  150. }
  151. /* 复选框项样式 */
  152. .checkbox-item {
  153. margin: 0 !important;
  154. display: flex !important;
  155. align-items: center !important;
  156. height: 28px;
  157. padding: 2px 6px;
  158. background: #fff;
  159. border: 1px solid #e4e7ed;
  160. border-radius: 4px;
  161. transition: all 0.15s cubic-bezier(.4,0,.2,1);
  162. cursor: pointer;
  163. box-shadow: none;
  164. }
  165. .checkbox-item:hover {
  166. border-color: #17b3a3;
  167. background: #f0fdfa;
  168. transform: translateY(-1px) scale(1.01);
  169. }
  170. .checkbox-item.is-checked {
  171. border-color: #17b3a3;
  172. background: #e6f7f4;
  173. }
  174. /* 复选框内部元素样式 */
  175. .checkbox-item .el-checkbox__input {
  176. margin-right: 8px;
  177. }
  178. .checkbox-item .el-checkbox__inner {
  179. width: 16px !important;
  180. height: 16px !important;
  181. border: 2px solid #dcdfe6 !important;
  182. border-radius: 4px !important;
  183. transition: all 0.2s ease !important;
  184. }
  185. .checkbox-item .el-checkbox__inner:hover {
  186. border-color: #409eff !important;
  187. }
  188. .checkbox-item .el-checkbox__input.is-checked .el-checkbox__inner {
  189. background-color: #409eff !important;
  190. border-color: #409eff !important;
  191. }
  192. .checkbox-item .el-checkbox__inner::after {
  193. height: 7px !important;
  194. left: 4px !important;
  195. top: 1px !important;
  196. width: 3px !important;
  197. border: 2px solid #fff !important;
  198. border-left: 0 !important;
  199. border-top: 0 !important;
  200. }
  201. .checkbox-item .el-checkbox__label {
  202. font-size: 13px !important;
  203. font-weight: 500 !important;
  204. color: #333 !important;
  205. padding-left: 0 !important;
  206. }
  207. .checkbox-item.is-checked .el-checkbox__label {
  208. color: #17b3a3 !important;
  209. }
  210. /* 对话框底部按钮 */
  211. .dialog-footer {
  212. text-align: center;
  213. padding-top: 12px;
  214. border-top: 1px solid #e4e7ed;
  215. margin-top: 350px;
  216. background: #fff;
  217. }
  218. .dialog-footer .el-button {
  219. min-width: 80px;
  220. height: 36px;
  221. font-size: 14px;
  222. border-radius: 6px;
  223. transition: all 0.2s;
  224. font-weight: 600;
  225. }
  226. .dialog-footer .el-button + .el-button {
  227. margin-left: 14px;
  228. }
  229. .dialog-footer .el-button--primary {
  230. background: linear-gradient(135deg, #17b3a3 0%, #1dc5ef 100%);
  231. border: none;
  232. box-shadow: 0 2px 8px rgba(23,179,163,0.12);
  233. }
  234. .dialog-footer .el-button--primary:hover {
  235. background: linear-gradient(135deg, #1dc5ef 0%, #17b3a3 100%);
  236. transform: translateY(-1px) scale(1.03);
  237. box-shadow: 0 4px 12px rgba(23,179,163,0.18);
  238. }
  239. .dialog-footer .el-button--primary:active {
  240. transform: translateY(0);
  241. box-shadow: 0 2px 6px rgba(64, 158, 255, 0.3);
  242. }
  243. /* 对话框整体样式优化 */
  244. .data-source-dialog {
  245. border-radius: 12px !important;
  246. box-shadow: 0 12px 32px rgba(0, 0, 0, 0.15) !important;
  247. max-height: 85vh !important;
  248. overflow: visible !important;
  249. }
  250. .data-source-dialog .el-dialog__header {
  251. padding: 20px 24px 16px !important;
  252. border-bottom: 1px solid #e4e7ed !important;
  253. }
  254. .data-source-dialog .el-dialog__title {
  255. font-size: 18px !important;
  256. font-weight: 600 !important;
  257. color: #303133 !important;
  258. }
  259. .data-source-dialog .el-dialog__body {
  260. padding: 20px 24px 0 24px !important;
  261. max-height: 65vh !important;
  262. overflow-y: auto !important;
  263. }
  264. .data-source-dialog .el-dialog__footer {
  265. padding: 16px 24px 20px !important;
  266. border-top: 1px solid #e4e7ed !important;
  267. background: #fff !important;
  268. position: sticky !important;
  269. bottom: 0 !important;
  270. }
  271. </style>