KeyConfig.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <template>
  2. <div class="keywords-config">
  3. <div class="key-title">
  4. <div>
  5. <span>关键词组设置</span>
  6. <span style="font-size: 14px"
  7. ><em style="color: #2cb7ca"> {{ keyCounts }}</em
  8. >/{{ maxCount }}</span
  9. >
  10. <p
  11. style="
  12. display: flex;
  13. align-items: center;
  14. font-size: 14px;
  15. color: #2cb7ca;
  16. "
  17. >
  18. 注:任意1组关键词组匹配成功即推送相关信息
  19. <img
  20. @click="setClickEvent"
  21. src="@/assets/images/icon/help.png"
  22. class="icon-help-img"
  23. />
  24. </p>
  25. </div>
  26. <div class="add-classify" @click="addClassifyFn">
  27. <i class="el-icon-plus"></i> 新增分类
  28. </div>
  29. </div>
  30. <div class="key-content">
  31. <KeyList
  32. ref="keyConfigRef"
  33. :list="keywordsList"
  34. :max-count="maxCount"
  35. :key="sort"
  36. @update="onUpdateKey"
  37. ></KeyList>
  38. </div>
  39. <el-dialog
  40. custom-class="sub-dialog small-dialog nesting-dialog r70"
  41. :visible.sync="add.dialog"
  42. :close-on-click-modal="false"
  43. :show-close="false"
  44. center
  45. width="460px"
  46. v-component-change-mount="{ selector: '.drawer-dialog' }"
  47. >
  48. <KeyCard @onCancel="add.dialog = false" @onConfirm="confirmEditClassFn">
  49. <div slot="header">新增关键词分类</div>
  50. <div class="class-edit-content">
  51. <div class="item">
  52. <div class="item-label">关键词分类:</div>
  53. <div class="item-value">
  54. <el-input
  55. class="custom-long-input"
  56. v-model.trim="add.className"
  57. maxlength="20"
  58. placeholder="请输入关键词分类"
  59. ></el-input>
  60. </div>
  61. </div>
  62. </div>
  63. </KeyCard>
  64. </el-dialog>
  65. </div>
  66. </template>
  67. <script>
  68. import { Input, Button, Dialog, RadioGroup, Radio } from 'element-ui'
  69. import KeyCard from '@/components/selector/SelectorCard'
  70. import KeyList from './components/List.vue'
  71. export default {
  72. name: 'keyConfig',
  73. props: {
  74. list: {
  75. type: Array,
  76. default() {
  77. return []
  78. }
  79. },
  80. maxCount: Number
  81. },
  82. components: {
  83. [Input.name]: Input,
  84. [Dialog.name]: Dialog,
  85. [Button.name]: Button,
  86. [RadioGroup.name]: RadioGroup,
  87. [Radio.name]: Radio,
  88. KeyCard,
  89. KeyList
  90. },
  91. data() {
  92. return {
  93. keywordsList: this.list,
  94. add: {
  95. dialog: false,
  96. className: ''
  97. },
  98. sort: 1,
  99. showSetKeyDialog: false
  100. }
  101. },
  102. computed: {
  103. keyCounts() {
  104. let count = 0
  105. this.keywordsList.forEach((v) => {
  106. if (v && v.a_key) {
  107. count += v.a_key.length
  108. }
  109. })
  110. return count
  111. }
  112. },
  113. methods: {
  114. setClickEvent() {
  115. this.$emit('closeDilog')
  116. },
  117. onUpdateKey(data) {
  118. this.keywordsList = data || []
  119. this.$emit('update', this.keywordsList)
  120. },
  121. parentGetCurEdit() {
  122. const t = this.$refs.keyConfigRef.getCurEdit()
  123. return t
  124. },
  125. // 新增关键词分类弹框
  126. addClassifyFn() {
  127. const t = this.parentGetCurEdit()
  128. if (t) return this.$toast('请先保存或取消正在操作的关键词组')
  129. this.add.className = ''
  130. this.add.dialog = true
  131. },
  132. // 确认添加分类
  133. confirmEditClassFn() {
  134. const classArr = this.getClassArray()
  135. const list = this.keywordsList
  136. if (classArr.indexOf(this.add.className) > -1) {
  137. return this.$message({
  138. type: 'warning',
  139. message: '分类名不能重复'
  140. })
  141. } else if (this.add.className === '') {
  142. return this.$message({
  143. type: 'warning',
  144. message: '分类名不能为空'
  145. })
  146. }
  147. if (list.length === 1 && list[0].s_item === '未分类') {
  148. list[0].s_item = this.add.className
  149. list[0].updatetime = parseInt(Date.now() / 1000)
  150. } else {
  151. list.push({
  152. s_item: this.add.className,
  153. a_key: [],
  154. showForm: false,
  155. updatetime: parseInt(Date.now() / 1000)
  156. })
  157. }
  158. this.add.dialog = false
  159. this.sort = Date.now()
  160. this.$refs.keyConfigRef.$forceUpdate()
  161. this.$emit('update', this.keywordsList)
  162. },
  163. // 获取所有分类名
  164. getClassArray() {
  165. const data = this.keywordsList
  166. const classArr = []
  167. data.forEach((v) => {
  168. if (v.s_item) {
  169. classArr.push(v.s_item)
  170. }
  171. })
  172. return classArr
  173. }
  174. }
  175. }
  176. </script>
  177. <style lang="scss" scoped>
  178. .keywords-config {
  179. margin-top: 12px;
  180. padding: 0 30px;
  181. background: #fff;
  182. .key-title {
  183. display: flex;
  184. justify-content: space-between;
  185. align-items: center;
  186. padding: 13px 0 8px;
  187. font-size: 18px;
  188. color: #1d1d1d;
  189. line-height: 28px;
  190. border-bottom: 1px solid #ececec;
  191. .icon-help-img {
  192. display: inline-block;
  193. width: 18px;
  194. height: 18px;
  195. margin: 0 7px 0 8px;
  196. cursor: pointer;
  197. }
  198. .add-classify {
  199. width: 110px;
  200. height: 38px;
  201. line-height: 38px;
  202. border: 1px solid #2cb7ca;
  203. border-radius: 6px;
  204. text-align: center;
  205. color: #2cb7ca;
  206. font-size: 14px;
  207. cursor: pointer;
  208. }
  209. }
  210. .key-content {
  211. padding: 20px 0;
  212. .classify-title {
  213. display: flex;
  214. align-items: center;
  215. .title-text {
  216. font-size: 16px;
  217. color: #1d1d1d;
  218. }
  219. .icon-edit,
  220. .icon-delete {
  221. display: inline-block;
  222. width: 16px;
  223. height: 16px;
  224. background-repeat: no-repeat;
  225. background-position: center center;
  226. cursor: pointer;
  227. &::before {
  228. content: '' !important;
  229. }
  230. }
  231. .icon-edit {
  232. margin: 0 10px;
  233. background-image: url('~@/assets/images/icon-edit.png');
  234. background-size: contain;
  235. }
  236. .icon-delete {
  237. background-image: url('~@/assets/images/icon-delete.png');
  238. background-size: contain;
  239. }
  240. }
  241. }
  242. }
  243. </style>