keyWord.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. var vm = new Vue({
  2. delimiters: ['${', '}'],
  3. el: '#app',
  4. data: {
  5. conf: {
  6. sessKey: '$data-vipsubscribe-keyword-list',
  7. keywordMax: 300
  8. },
  9. batchDeleteState: false, // 是否在批量删除状态
  10. userData: {}, // getUserInfo接口用户原始数据
  11. keywordsGroupList: [], // 所有关键词列表
  12. groupNameList: [], // 关键词分类名称列表
  13. // 当前信息
  14. filter: {
  15. loaded: false, // 是否请求加载完成
  16. pickerShow: false, // picker是否显示
  17. groupName: '', // 为空表示全部
  18. allKeywordsList: [], // 筛选前的数组
  19. keywordsList: [], // 筛选后的数组
  20. },
  21. dialog: {
  22. fastImport: false, // 快速导入弹框
  23. upgrade: false // 关键词升级提示弹框
  24. },
  25. tip: {
  26. fastImport: true, // 控制快速导入入口的显示隐藏
  27. i_vip_fastimport: 0,
  28. ordinarykc: 0
  29. },
  30. scrollTop: 0 // 记录滚动高度
  31. },
  32. computed: {
  33. keyListSorted: function () {
  34. return this.filter.keywordsList.sort(function (a, b) {
  35. return b.updatetime - a.updatetime
  36. })
  37. },
  38. fastImportTipShow: function () {
  39. var needShow = this.tip.i_vip_fastimport == 0 && this.tip.ordinarykc > 0
  40. return needShow && this.filter.loaded && this.tip.fastImport
  41. },
  42. listShow: function () {
  43. return this.filter.keywordsList.length !== 0 && this.filter.loaded
  44. },
  45. emptyShow: function () {
  46. return this.filter.keywordsList.length === 0 && this.filter.loaded
  47. },
  48. selectedCount: function () {
  49. var selectedArr = this.getSelectedArr()
  50. return selectedArr.length
  51. },
  52. totalKeywordsCount: function () {
  53. // var count = 0
  54. // this.filter.allKeywordsList.forEach(function (item) {
  55. // if (item.matchway == 1) {
  56. // // 模糊匹配
  57. // var key = item.key
  58. // if (Array.isArray(item.appendkey)) {
  59. // key = key.concat(item.appendkey)
  60. // }
  61. // count += key.length
  62. // } else {
  63. // // 精准匹配(matchway:0/undefined)
  64. // count++
  65. // }
  66. // })
  67. return this.filter.allKeywordsList.length
  68. }
  69. },
  70. created: function () {
  71. this.restoreState()
  72. this.getKeywordsGroupList(true)
  73. },
  74. mounted: function () {},
  75. methods: {
  76. showLoading: function () {
  77. return this.$toast.loading({
  78. duration: 0,
  79. forbidClick: true,
  80. message: 'loading...',
  81. })
  82. },
  83. showToast: function (message) {
  84. return this.$toast({
  85. duration: 1500,
  86. forbidClick: true,
  87. message: message,
  88. })
  89. },
  90. showDialog: function (conf) {
  91. var defaultConf = {
  92. title: '提示',
  93. message: 'message',
  94. className: 'j-confirm-dialog',
  95. showConfirmButton: true,
  96. showCancelButton: true,
  97. confirmButtonColor: '#2abed1'
  98. }
  99. if (conf) {
  100. Object.assign(defaultConf, conf)
  101. }
  102. return this.$dialog.confirm(defaultConf)
  103. },
  104. // 对象转form
  105. qsStringify: function (t) {
  106. var arr = []
  107. for (var k in t) {
  108. arr.push(`${k}=${t[k]}`)
  109. }
  110. return arr.join('&')
  111. },
  112. scrollTo: function (scrollTop, animate) {
  113. var jMain = this.$refs.jMain
  114. if (animate) {
  115. $(jMain).animate({ scrollTop: scrollTop }, 300)
  116. } else {
  117. $(jMain).scrollTop(scrollTop)
  118. }
  119. },
  120. getKeywordsGroupList: function (needLoading) {
  121. var _this = this
  122. if (needLoading) {
  123. var loading = this.showLoading()
  124. }
  125. $.ajax({
  126. type: 'POST',
  127. url: '/subscribepay/afterPay/getUserInfo?t=' + Date.now(),
  128. success: function (res) {
  129. if (needLoading) {
  130. loading && loading.clear()
  131. }
  132. if (res && res.userData) {
  133. _this.userData = res.userData
  134. if (res.userData) {
  135. _this.tip.i_vip_fastimport = res.userData.i_vip_fastimport
  136. _this.tip.ordinarykc = res.userData.ordinarykc
  137. // 关键词弹窗提醒 fasle:需要弹窗 true:不需要弹窗
  138. if (!res.userData.b_keytip) {
  139. _this.dialog.upgrade = true
  140. }
  141. }
  142. if (res.userData && res.userData.o_vipjy) {
  143. // 整理数据
  144. var groupList = _this.addInfoToKeyItem(res.userData.o_vipjy.a_items)
  145. var groupNameList = _this.getGroupNameList(groupList)
  146. _this.keywordsGroupList = groupList
  147. _this.groupNameList = groupNameList
  148. _this.doFilter(_this.filter.groupName)
  149. _this.filter.allKeywordsList = _this.filterKeywordsList()
  150. if (needLoading && _this.scrollTop != 0) {
  151. _this.$nextTick(function () {
  152. _this.scrollTo(_this.scrollTop)
  153. _this.scrollTop = 0
  154. })
  155. }
  156. }
  157. }
  158. },
  159. error: function () {
  160. if (needLoading) {
  161. loading && loading.clear()
  162. }
  163. },
  164. complete: function () {
  165. _this.filter.loaded = true
  166. }
  167. })
  168. },
  169. // 向关键词中添加一些信息
  170. addInfoToKeyItem: function (groupList) {
  171. var _this = this
  172. if (!Array.isArray(groupList)) return []
  173. var arr = []
  174. groupList.forEach(function (keywordsList, index) {
  175. if (keywordsList && Array.isArray(keywordsList.a_key)) {
  176. keywordsList.groupIndex = index
  177. if (!keywordsList.updatetime) {
  178. keywordsList.updatetime = 0
  179. }
  180. keywordsList.a_key.forEach(function (keyword, iindex) {
  181. // 添加一些其他信息
  182. keyword.groupName = keywordsList.s_item // 分类名
  183. keyword.groupIndex = index // 该关键词所在分类 在分类列表中的索引
  184. keyword.keyIndex = iindex // 该关键词在其所在分类中的索引
  185. if (!keyword.updatetime) {
  186. keyword.updatetime = 0
  187. }
  188. })
  189. arr.push(keywordsList)
  190. }
  191. })
  192. return arr
  193. },
  194. getGroupNameList: function (keywordsGroupList) {
  195. var groupNameList = []
  196. if (!Array.isArray(keywordsGroupList)) return groupNameList
  197. keywordsGroupList.forEach(function (item) {
  198. if (item) {
  199. var count = Array.isArray(item.a_key) ? item.a_key.length : 0
  200. groupNameList.push({
  201. name: item.s_item, // 分类名
  202. count: count, // 分类下有多少个关键词
  203. groupIndex: item.groupIndex,
  204. updatetime: item.updatetime
  205. })
  206. }
  207. })
  208. return groupNameList
  209. },
  210. calcKeyInfo: function (item) {
  211. // 匹配方式 item.matchway 0/null精准 1模糊
  212. var key = item.key
  213. var notkey = []
  214. if (Array.isArray(item.appendkey)) {
  215. key = key.concat(item.appendkey)
  216. }
  217. if (Array.isArray(item.notkey)) {
  218. notkey = item.notkey
  219. }
  220. return {
  221. key: key.join(' '),
  222. notkey: notkey.join(' '),
  223. matchWay: item.matchway == 1 ? '模糊' : '精准',
  224. matchWayClass: item.matchway == 1 ? 'tag-orange' : 'tag-green'
  225. }
  226. },
  227. showFilterPicker: function (f) {
  228. this.filter.pickerShow = f
  229. },
  230. checkThisGroup: function (item) {
  231. var groupName = ''
  232. if (item) {
  233. groupName = item.name
  234. } else {
  235. groupName = ''
  236. }
  237. this.doFilter(groupName)
  238. this.showFilterPicker(false)
  239. },
  240. doFilter: function (groupName) {
  241. var _this = this
  242. this.filter.groupName = groupName
  243. var rList = this.filterKeywordsList(groupName)
  244. this.filter.keywordsList = rList
  245. this.$nextTick(function () {
  246. _this.scrollTo(0)
  247. })
  248. },
  249. // 筛选分类列表
  250. filterKeywordsList: function (filterName) {
  251. var list = []
  252. // 筛选关键词
  253. this.keywordsGroupList.forEach(function (keywordsList) {
  254. if (Array.isArray(keywordsList.a_key)) {
  255. keywordsList.a_key.forEach(function (keyword) {
  256. // 筛选全部(筛选词为空),需要把关键词所属分类信息记录
  257. if (!filterName) {
  258. list.push(keyword)
  259. } else {
  260. if (filterName === keywordsList.s_item) {
  261. list.push(keyword)
  262. }
  263. }
  264. })
  265. }
  266. })
  267. // 给新的list添加checked
  268. list = JSON.parse(JSON.stringify(list))
  269. list.forEach(function (item) {
  270. item.checked = false
  271. item.calcInfo = this.calcKeyInfo(item)
  272. }.bind(this))
  273. return list
  274. },
  275. clickKeyCard: function (item) {
  276. if (this.batchDeleteState) {
  277. // 执行点击选中逻辑
  278. // 如果关键词组下有关键词,则不能点击
  279. item.checked = !item.checked
  280. } else {
  281. // type: edit编辑、add新增
  282. // gIndex: groupIndex 该关键词所在分类 在分类列表中的索引
  283. // kIndex: keyIndex 该关键词在其所在分类中的索引
  284. this.savePageState()
  285. location.href = `/front/vipsubscribe/toSetinfoPage?type=edit&gIndex=${item.groupIndex}&kIndex=${item.keyIndex}`
  286. }
  287. },
  288. batchDeleteStateChange: function () {
  289. this.batchDeleteState = !this.batchDeleteState
  290. },
  291. batchDelete: function () {
  292. var _this = this
  293. if (this.selectedCount <= 0) return
  294. this.showDialog({
  295. title: '',
  296. message: '确定删除所选' + this.selectedCount + '个关键词吗?',
  297. className: 'j-confirm-dialog text-center',
  298. }).then(function () {
  299. console.log('确认批量删除关键词')
  300. _this.batchDeleteConfirmed()
  301. })
  302. .catch(function() {
  303. console.log('取消批量删除关键词')
  304. })
  305. },
  306. getSelectedArr: function () {
  307. var selectedArr = []
  308. this.filter.keywordsList.forEach(function (item) {
  309. if (item.checked) {
  310. selectedArr.push(item)
  311. }
  312. })
  313. return selectedArr
  314. },
  315. getDeleteKey: function () {
  316. var deleteKeyArr = {}
  317. var deleteKey = {}
  318. var selectedArr = this.getSelectedArr()
  319. selectedArr.forEach(function (item) {
  320. var groupIndex = item.groupIndex
  321. var keyIndex = item.keyIndex
  322. if (deleteKeyArr[groupIndex]) {
  323. deleteKeyArr[groupIndex].push(keyIndex)
  324. } else {
  325. deleteKeyArr[groupIndex] = [keyIndex]
  326. }
  327. })
  328. for (var key in deleteKeyArr) {
  329. if (Array.isArray(deleteKeyArr[key])) {
  330. deleteKeyArr[key] = deleteKeyArr[key].sort(function (a, b) { return a - b })
  331. deleteKey[key] = deleteKeyArr[key].join(',')
  332. }
  333. }
  334. return deleteKey
  335. },
  336. batchDeleteConfirmed: function () {
  337. var deleteKey = this.getDeleteKey()
  338. if (Object.keys(deleteKey).length === 0) return
  339. var loading = this.showLoading()
  340. var _this = this
  341. $.ajax({
  342. url: '/subscribepay/afterPay/setUserInfo',
  343. type: 'POST',
  344. data: {
  345. pageType: 'keyWords',
  346. actionType: 'DK',
  347. delete_key: JSON.stringify(deleteKey)
  348. },
  349. success: function (res) {
  350. loading && loading.clear()
  351. if (res.flag) {
  352. _this.showToast('删除成功')
  353. _this.getKeywordsGroupList()
  354. _this.batchDeleteState = false
  355. } else {
  356. _this.showToast(res.msg ? res.msg : '删除失败' )
  357. }
  358. },
  359. error: function () {
  360. loading && loading.clear()
  361. }
  362. })
  363. },
  364. beforeKeySwipeCellClose: function (e) {
  365. // position 为关闭时点击的位置
  366. // instance 为对应的 SwipeCell 实例
  367. var position = e.position
  368. var instance = e.instance
  369. var index = e.name // item.groupIndex-item.keyIndex
  370. switch (position) {
  371. case 'left': {
  372. break
  373. }
  374. case 'cell': {
  375. instance.close()
  376. break
  377. }
  378. case 'outside': {
  379. instance.close()
  380. break
  381. }
  382. case 'right': {
  383. this.delThisKey(index, instance)
  384. break
  385. }
  386. default: {
  387. break
  388. }
  389. }
  390. },
  391. getGroupFromIndex: function (gIndex, kIndex) {
  392. var groupItem = {}
  393. this.filter.keywordsList.some(function (item) {
  394. if (item) {
  395. var gotThis = item.groupIndex == gIndex && item.keyIndex == kIndex
  396. if (gotThis) {
  397. groupItem = item
  398. }
  399. return gotThis
  400. }
  401. })
  402. return groupItem
  403. },
  404. /**
  405. * 删除单个关键词
  406. * @param {number} index 当前关键词在列表中的index
  407. * @param {Object} instance SwipeCell的实例
  408. */
  409. delThisKey: function (index, instance) {
  410. var _this = this
  411. // 需要找到当前关键词组的item
  412. var indexArr = index.split('-')
  413. var gIndex = indexArr[0]
  414. var kIndex = indexArr[1]
  415. var key = this.getGroupFromIndex(gIndex, kIndex)
  416. this.showDialog({
  417. title: '',
  418. message: '确定删除当前关键词?',
  419. confirmButtonText: '删除',
  420. className: 'j-confirm-dialog text-center'
  421. }).then(function () {
  422. // 点击确定,将当前关键词在批量选选择中,选中
  423. key.checked = true
  424. _this.batchDeleteConfirmed()
  425. }).catch(function () {
  426. console.log('取消删除关键词')
  427. })
  428. },
  429. // 根据分类名,得到分类索引
  430. getGroupIndexWithGroupName: function (gn) {
  431. var groupIndex = -1
  432. this.keywordsGroupList.forEach(function(item) {
  433. if (gn === item.s_item) {
  434. groupIndex = item.groupIndex
  435. }
  436. })
  437. return groupIndex
  438. },
  439. addKeyWord: function () {
  440. var query = {
  441. type: 'add'
  442. }
  443. // 新增,往哪个分组下新增(默认往未分组下新增)
  444. var groupIndex = this.getGroupIndexWithGroupName(this.filter.groupName)
  445. if (groupIndex != -1) {
  446. query.gIndex = groupIndex
  447. }
  448. this.savePageState()
  449. var queryString = this.qsStringify(query)
  450. location.href = '/front/vipsubscribe/toSetinfoPage' + '?' + queryString
  451. },
  452. toKeyManagePage: function () {
  453. this.filter.pickerShow = false
  454. this.savePageState()
  455. location.href = '/front/vipsubscribe/toSetmanagePage'
  456. },
  457. fastImportDialogShow: function () {
  458. this.dialog.fastImport = true
  459. },
  460. fastImport: function () {
  461. var _this = this
  462. var loading = this.showLoading()
  463. $.ajax({
  464. type: 'POST',
  465. url: '/subscribepay/afterPay/fastImport',
  466. data: {
  467. c_index: _this.keywordsGroupList.length,
  468. c_name: '未分类'
  469. },
  470. success: function (r) {
  471. loading && loading.clear()
  472. if (r.flagInt == 1) {
  473. _this.showToast('成功导入' + r.kwMap.length + '个关键词')
  474. _this.getKeywordsGroupList()
  475. } else {
  476. _this.showToast('导入失败')
  477. }
  478. try {
  479. JyObj.checkLab(); //刷新搜索首页和订阅首页
  480. sessionStorage.reloadHomePage = true;
  481. sessionStorage.reloadSubPage = true;
  482. } catch (e) {}
  483. },
  484. error: function () {
  485. loading && loading.clear()
  486. }
  487. })
  488. },
  489. upgradeDialogClose: function () {
  490. $.ajax({
  491. type: 'POST',
  492. url: '/subscribepay/afterPay/setUserInfo',
  493. data: {
  494. pageType: 'keytip'
  495. }
  496. })
  497. },
  498. // 恢复数据
  499. restoreState: function () {
  500. var $data = sessionStorage.getItem(this.conf.sessKey)
  501. if ($data) {
  502. $data = JSON.parse($data)
  503. Object.assign(this.filter, $data.filter || {})
  504. this.scrollTop = $data.scrollTop
  505. sessionStorage.removeItem(this.conf.sessKey)
  506. }
  507. return !!$data
  508. },
  509. // 保存数据
  510. savePageState: function () {
  511. this.scrollTop = $(this.$refs.jMain).scrollTop()
  512. var data = {
  513. filter: {
  514. groupName: this.filter.groupName
  515. },
  516. scrollTop: this.scrollTop
  517. }
  518. sessionStorage.setItem(this.conf.sessKey, JSON.stringify(data))
  519. }
  520. }
  521. })