keyWord.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. <style>
  2. .select-table .ant-table-thead > tr > th,
  3. .select-table .ant-table-tbody > tr > td {
  4. padding: 0 !important;
  5. }
  6. .select-table .ant-table {
  7. font-size: 12px;
  8. }
  9. .demo-infinite-container {
  10. border: 1px solid #e8e8e8;
  11. border-radius: 4px;
  12. overflow: auto;
  13. padding: 8px 24px;
  14. height: 300px;
  15. }
  16. .demo-loading-container {
  17. position: absolute;
  18. bottom: 40px;
  19. width: 100%;
  20. text-align: center;
  21. }
  22. </style>
  23. <style lang="scss" scoped>
  24. .require-check {
  25. ::v-deep .ant-form-item-label {
  26. label::before {
  27. display: inline-block;
  28. margin-right: 4px;
  29. color: #f5222d;
  30. font-size: 14px;
  31. font-family: SimSun, sans-serif;
  32. line-height: 1;
  33. content: '*';
  34. }
  35. }
  36. }
  37. </style>
  38. <template>
  39. <div>
  40. <a-form-item
  41. label="关键字"
  42. v-clickoutside="handleClose"
  43. style="width: 100%"
  44. class="select-table"
  45. :class="{ 'require-check': requireCheck }"
  46. >
  47. <a-input
  48. @focus="
  49. topMiddle = true
  50. getData()
  51. "
  52. v-model="keyValue"
  53. @change="getData"
  54. :disabled="disabled"
  55. @keyup.enter.native="okWord"
  56. addon-after="选中后按回车键添加"
  57. />
  58. <div
  59. v-show="topMiddle"
  60. style="
  61. background: white;
  62. padding: 10px;
  63. box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.15);
  64. position: absolute;
  65. z-index: 1000;
  66. width: 100%;
  67. "
  68. class="demo-infinite-container"
  69. >
  70. <!-- <a-list :data-source="data">
  71. <a-list-item slot="renderItem" slot-scope="item" @click="showProject(item)">
  72. <a-list-item-meta>
  73. <a slot="title">{{ item.word }}</a>
  74. </a-list-item-meta>
  75. </a-list-item>
  76. <div v-if="loading && !busy" class="demo-loading-container">
  77. <a-spin />
  78. </div>
  79. </a-list> -->
  80. <a-checkbox-group
  81. v-model="selectDescriptionArr"
  82. style="width:100%;margin-top:10px"
  83. v-on:keyup.enter.native="okWord"
  84. >
  85. <a-list bordered :data-source="data" style="width:100%;max-height: 450px;overflow:auto">
  86. <a-list-item slot="renderItem" slot-scope="item, index">
  87. <a-checkbox :value="item.word">
  88. {{ item.word }}
  89. </a-checkbox>
  90. </a-list-item>
  91. </a-list>
  92. </a-checkbox-group>
  93. </div>
  94. </a-form-item>
  95. <a-table
  96. :columns="columns"
  97. :dataSource="dataSource"
  98. :pagination="false"
  99. bordered
  100. size="middle"
  101. style="word-break: break-all;font-size:16px;font-weight:600"
  102. id="outTable"
  103. ref="accountTable"
  104. >
  105. <span slot="query_word" slot-scope="text, record">
  106. {{ text }}
  107. </span>
  108. <span slot="recommended_word" slot-scope="text, record">
  109. {{ !!text[0] ? text.join() : '-' }}
  110. </span>
  111. <span slot="action" slot-scope="text, record">
  112. <a @click.stop="deleteScript(record)">删除</a>
  113. </span>
  114. </a-table>
  115. </div>
  116. </template>
  117. <script>
  118. import { getAction, postAction } from '@/api/manage'
  119. import moment from 'moment'
  120. import { mapGetters } from 'vuex'
  121. import jq from 'jquery'
  122. import infiniteScroll from 'vue-infinite-scroll'
  123. const clickoutside = {
  124. // 初始化指令
  125. bind(el, binding, vnode) {
  126. function documentHandler(e) {
  127. // 这里判断点击的元素是否是本身,是本身,则返回
  128. if (el.contains(e.target)) {
  129. return false
  130. }
  131. // 判断指令中是否绑定了函数
  132. if (binding.expression) {
  133. // 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法
  134. binding.value(e)
  135. }
  136. }
  137. // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
  138. el.__vueClickOutside__ = documentHandler
  139. document.addEventListener('click', documentHandler)
  140. },
  141. update() {},
  142. unbind(el, binding) {
  143. // 解除事件监听
  144. document.removeEventListener('click', el.__vueClickOutside__)
  145. delete el.__vueClickOutside__
  146. }
  147. }
  148. let TTcolumns = [
  149. {
  150. title: '关键字',
  151. dataIndex: 'query_word',
  152. scopedSlots: { customRender: 'query_word' },
  153. align: 'center',
  154. key: 'query_word'
  155. },
  156. {
  157. title: '推荐词',
  158. dataIndex: 'recommended_word',
  159. scopedSlots: { customRender: 'recommended_word' },
  160. align: 'center',
  161. key: 'recommended_word'
  162. },
  163. {
  164. title: '操作',
  165. dataIndex: 'action',
  166. scopedSlots: { customRender: 'action' },
  167. align: 'center',
  168. key: 'action'
  169. }
  170. ]
  171. export default {
  172. name: 'select-pagination',
  173. components: {},
  174. directives: { clickoutside, infiniteScroll },
  175. props: {
  176. projectId: {
  177. type: [String, Number, Array],
  178. default() {
  179. return []
  180. }
  181. },
  182. allScript: {
  183. type: [String, Number, Array],
  184. default() {
  185. return []
  186. }
  187. },
  188. type: {
  189. type: String,
  190. default() {
  191. return ''
  192. }
  193. },
  194. labelCol: {
  195. type: Object,
  196. default() {
  197. return {
  198. xs: { span: 24 },
  199. sm: { span: 5 }
  200. }
  201. }
  202. },
  203. disabled: {
  204. type: Boolean,
  205. default() {
  206. return false
  207. }
  208. },
  209. requireCheck: {
  210. type: Boolean,
  211. default() {
  212. return false
  213. }
  214. }
  215. },
  216. data() {
  217. return {
  218. loading: false,
  219. busy: false,
  220. wrapperCol: {
  221. xs: { span: 24 },
  222. sm: { span: 12 }
  223. },
  224. selectedRowKeys: [],
  225. selectedRowKeysValue: [],
  226. topMiddle: false,
  227. keyValue: '',
  228. data: [],
  229. selectDescriptionArr: [],
  230. dataElse: [],
  231. ipagination: {
  232. current: 0,
  233. pageSize: 20
  234. },
  235. columns: TTcolumns,
  236. dataSource: [],
  237. rowClick: (record, index) => ({
  238. // 事件
  239. on: {
  240. click: () => {
  241. // var str =
  242. // record.mediaId == '1'
  243. // ? '头条'
  244. // : record.mediaId == '2'
  245. // ? '快手'
  246. // : record.mediaId == '3'
  247. // ? '头条内广'
  248. // : '快手内广'
  249. this.keyValue = record.productName
  250. this.topMiddle = false
  251. this.data = this.dataElse
  252. // this.$emit('update:projectId', record.id)
  253. }
  254. }
  255. })
  256. }
  257. },
  258. computed: {},
  259. filters: {},
  260. methods: {
  261. deleteScript(item) {
  262. var index = this.dataSource.findIndex(i=>i==item.query_word)
  263. this.dataSource.splice(index,1)
  264. var indexRemove = this.projectId.findIndex(i=>i==item.query_word)
  265. this.projectId.splice(indexRemove,1)
  266. },
  267. showProject(record) {
  268. var str =
  269. record.mediaId == '1'
  270. ? '头条'
  271. : record.mediaId == '2'
  272. ? '快手'
  273. : record.mediaId == '3'
  274. ? '头条内广'
  275. : '快手内广'
  276. this.keyValue = record.productName
  277. this.topMiddle = false
  278. this.$emit('update:projectId', record.id)
  279. },
  280. ...mapGetters(['nickname', 'avatar', 'userInfo']),
  281. onSelectChange(selectedRowKeys, selectionRows) {
  282. this.selectedRowKeys = selectedRowKeys
  283. this.selectedRowKeysValue = selectionRows.map(item => {
  284. return { orientationId: item.orientationId, orientationName: item.orientationName }
  285. })
  286. },
  287. getData() {
  288. if (this.keyValue == '') {
  289. this.$emit('update:projectId', this.projectId)
  290. }
  291. if (!!this.keyValue) {
  292. this.topMiddle = true
  293. this.ipagination.current = 1
  294. postAction(process.env.VUE_APP_BASE_SCRIPT_URL + '/related_words?word=' + this.keyValue).then(res => {
  295. if (res.code == 0) {
  296. this.data = res.result.map((item, index) => {
  297. return {
  298. productId: item,
  299. key: index,
  300. word: item
  301. }
  302. })
  303. // if (this.type === 'taobao') {
  304. // this.data = defaultList.filter(item => item.productId === 1410280)
  305. // } else {
  306. // this.data = defaultList
  307. // }
  308. // this.dataElse = res.result.records.map((item, index) => {
  309. // return {
  310. // ...item,
  311. // projectId: item.projectId + '',
  312. // key: index,
  313. // }
  314. // })
  315. }
  316. })
  317. } else {
  318. this.data = []
  319. this.selectDescriptionArr = []
  320. }
  321. },
  322. okWord() {
  323. if (this.projectId.findIndex(item => item == this.keyValue) > -1) {
  324. } else {
  325. this.projectId.push(this.keyValue)
  326. }
  327. var index = this.dataSource.findIndex(item => item.query_word == this.keyValue)
  328. if (index > -1) {
  329. this.dataSource[index].recommended_word = this.selectDescriptionArr
  330. } else {
  331. this.dataSource.push({ query_word: this.keyValue, recommended_word: this.selectDescriptionArr })
  332. }
  333. this.keyValue = ''
  334. this.selectDescriptionArr = []
  335. this.$nextTick(()=>{
  336. setTimeout(()=>{
  337. this.$emit('update:allScript', this.dataSource)
  338. },100)
  339. })
  340. this.handleClose()
  341. },
  342. handleClose() {
  343. this.topMiddle = false
  344. if (!!!this.projectId) {
  345. this.keyValue = ''
  346. }
  347. },
  348. // allData() {
  349. // getAction('/ctop/product/getUserProductList', {
  350. // userId: this.userInfo().id,
  351. // pageSize: this.ipagination.pageSize,
  352. // pageNo: this.ipagination.current,
  353. // }).then((res) => {
  354. // if (res.code == 0) {
  355. // this.data = res.result.records.map((item, index) => {
  356. // return {
  357. // ...item,
  358. // projectId: item.projectId + '',
  359. // key: index,
  360. // }
  361. // })
  362. // this.dataElse = res.result.records.map((item, index) => {
  363. // return {
  364. // ...item,
  365. // projectId: item.projectId + '',
  366. // key: index,
  367. // }
  368. // })
  369. // }
  370. // })
  371. // },
  372. handleInfiniteOnLoad() {
  373. const data = this.data
  374. this.loading = true
  375. this.ipagination.current++
  376. // this.fetchData((res) => {
  377. // this.data = data.concat(res.results)
  378. // this.loading = false
  379. // })
  380. // getAction('/ctop/product/getUserProductList', {
  381. // userId: this.userInfo().id,
  382. // pageSize: this.ipagination.pageSize,
  383. // pageNo: this.ipagination.current,
  384. // productName: this.keyValue
  385. // }).then(res => {
  386. // if (res.code == 0) {
  387. // this.busy = true
  388. // let defaultList = res.result.records.map((item, index) => {
  389. // return {
  390. // ...item,
  391. // projectId: item.projectId + ''
  392. // }
  393. // })
  394. // this.data = data.concat()
  395. // if (this.type === 'taobao') {
  396. // this.data = defaultList.filter(item => item.productId === 1410280)
  397. // } else {
  398. // this.data = data.concat(defaultList)
  399. // }
  400. // // this.data = res.result.records.map((item, index) => {
  401. // // return {
  402. // // ...item,
  403. // // projectId: item.projectId + '',
  404. // // key: index,
  405. // // }
  406. // // })
  407. // // this.dataElse = res.result.records.map((item, index) => {
  408. // // return {
  409. // // ...item,
  410. // // projectId: item.projectId + '',
  411. // // key: index,
  412. // // }
  413. // // })
  414. // }
  415. // })
  416. }
  417. },
  418. watch: {
  419. projectId(n, o) {
  420. if (n == '') {
  421. this.keyValue = ''
  422. } else {
  423. }
  424. }
  425. },
  426. mounted() {}
  427. }
  428. </script>
  429. <style type="text/css">
  430. .plug-timer-grid {
  431. width: 100%;
  432. }
  433. .plug-timer-grid td,
  434. .plug-timer-grid th {
  435. border: 1px solid #97b4d1;
  436. text-align: center; /*cursor:pointer;*/
  437. font-size: 10px;
  438. line-height: 10px;
  439. }
  440. .Selected {
  441. background-color: rgb(102, 162, 243);
  442. opacity: 0.5;
  443. }
  444. .plug-timer-grid {
  445. border-collapse: collapse;
  446. z-index: 4;
  447. }
  448. .plug-timer-grid thead tr {
  449. display: table-row;
  450. vertical-align: inherit;
  451. border-color: inherit;
  452. }
  453. .group-creat table td {
  454. height: 20px;
  455. max-width: 5px;
  456. font-size: 12px;
  457. text-align: center;
  458. vertical-align: middle;
  459. overflow: hidden;
  460. transition: background 0.5s;
  461. -webkit-transition: background 0.5s;
  462. }
  463. .plug-timer-grid tbody th {
  464. width: 4%;
  465. }
  466. .plug-timer-grid tbody tr td {
  467. width: 2%;
  468. }
  469. /*.clear{*/
  470. /* margin:20px 0px 20px 0px;*/
  471. /*}*/
  472. </style>