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

EditTopics.vue 13 kB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. <template>
  2. <div>
  3. <div class="input-search">
  4. <el-input v-model="input" clearable :autofocus="true" @input="changeValue" id="topics_input" @keyup.enter.native="postTopic" placeholder="搜索或创建标签">
  5. </el-input>
  6. <div class="scrolling-menu">
  7. <div v-if="showSearchTopic" class="item-text" v-for="(arr,i) in array" @click="addTopics(i,arr)">
  8. <div class="icon-wrapper">
  9. <i style="line-height: 1.5;color: #303643;font-weight: 900;" v-if="showInitTopic[i]" class="el-icon-check" ></i>
  10. </div>
  11. <div class="text">{{arr.topic_name}} </div>
  12. </div>
  13. <div v-if="showInputValue" class="addition item-text" @click="postTopic">
  14. 点击或回车添加<b class="user-add-label-text">{{input}}</b>标签
  15. </div>
  16. <div v-if="showAddTopic" class="item-text" @click="addPostTopic">
  17. <div class="icon-wrapper">
  18. <i style="line-height: 1.5;color: #303643;font-weight: 900;" v-if="showAddFlage" class="el-icon-check" ></i>
  19. </div>
  20. <div class="text">{{input}}</div>
  21. </div>
  22. </div>
  23. </div>
  24. </div>
  25. </template>
  26. <script>
  27. const {AppSubUrl, StaticUrlPrefix, csrf} = window.config;
  28. import $ from 'jquery'
  29. export default {
  30. data() {
  31. return {
  32. input:'',
  33. params:{},
  34. showInputValue:false,
  35. showFlag:-1,
  36. array:[],
  37. showAddTopic:false,
  38. showAddFlage:false,
  39. showSearchTopic:true,
  40. postUrl:'',
  41. arrayTopics:[],
  42. showInitTopic:[],
  43. };
  44. },
  45. methods: {
  46. addTopics(item,array){
  47. if(!this.showInitTopic[item]){
  48. this.arrayTopics.push(array.topic_name)
  49. let topics = this.arrayTopics
  50. let strTopics = topics.join(',')
  51. let data = this.qs.stringify({
  52. _csrf:csrf,
  53. topics:strTopics
  54. })
  55. this.Post(data,topics)
  56. this.$set(this.showInitTopic,item,true)
  57. $('#repo-topics1').children('span').remove()
  58. }else{
  59. this.arrayTopics=this.arrayTopics.filter(ele=>{
  60. return ele !== array.topic_name
  61. })
  62. let topics = this.arrayTopics
  63. let strTopics = topics.join(',')
  64. let data = this.qs.stringify({
  65. _csrf:csrf,
  66. topics:strTopics
  67. })
  68. this.Post(data,topics)
  69. this.$set(this.showInitTopic,item,false)
  70. if(this.arrayTopics.length===0){
  71. console.log("set empty")
  72. $('#repo-topics1').append('<span class="no-description text-italic">暂无标签</span>')
  73. }else{
  74. $('#repo-topics1').children('span').remove()
  75. }
  76. }
  77. },
  78. changeValue(){
  79. if (this.input === ''){
  80. this.array = this.arrayTopics
  81. let data = []
  82. this.showInitTopic = []
  83. this.array.forEach((element,index) => {
  84. let item = {}
  85. item.topic_name = element
  86. data.push(item)
  87. this.showInitTopic.push(true)
  88. });
  89. this.array = data
  90. this.showInputValue = false
  91. this.showSearchTopic = true
  92. }
  93. else if(this.arrayTopics.indexOf(this.input)>-1){
  94. this.showInputValue = false
  95. this.showSearchTopic = false
  96. }else{
  97. this.showInitTopic = []
  98. let timestamp=new Date().getTime()
  99. this.params.q = this.input
  100. this.params._ = timestamp
  101. this.$axios.get('/api/v1/topics/search',{
  102. params:this.params
  103. }).then((res)=>{
  104. this.array = res.data.topics
  105. this.array.forEach((element,index) => {
  106. if (this.arrayTopics.indexOf(element.topic_name)>-1){
  107. this.showInitTopic.push(true)
  108. }else{
  109. this.showInitTopic.push(false)
  110. }
  111. });
  112. })
  113. this.showInputValue = true
  114. this.showSearchTopic = true
  115. }
  116. this.showAddTopic = false
  117. },
  118. Post(data,topics){
  119. this.$axios.post(this.postUrl,data).then(res=>{
  120. const viewDiv = $('#repo-topics1');
  121. viewDiv.children('.topic').remove();
  122. if (topics.length) {
  123. const topicArray = topics;
  124. const last = viewDiv.children('a').last();
  125. for (let i = 0; i < topicArray.length; i++) {
  126. const link = $('<a class="ui repo-topic small label topic"></a>');
  127. link.attr(
  128. 'href',
  129. `${AppSubUrl}/explore/repos?q=${encodeURIComponent(
  130. topicArray[i]
  131. )}&topic=1`
  132. );
  133. link.text(topicArray[i]);
  134. // link.insertBefore(last);
  135. viewDiv.append(link)
  136. }
  137. }
  138. viewDiv.show();
  139. })
  140. },
  141. postTopic(){
  142. const patter = /^[\u4e00-\u9fa5a-zA-Z0-9][\u4e00-\u9fa5a-zA-Z0-9-]{0,34}$/
  143. let regexp = patter.test(this.input)
  144. console.log("regexp",regexp)
  145. if(!regexp){
  146. this.$notify({
  147. message: '标签名必须以中文、字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符',
  148. duration: 3000,
  149. type:'error'
  150. });
  151. return
  152. }else{
  153. let topic = this.input
  154. this.arrayTopics.push(topic)
  155. let topics = this.arrayTopics
  156. let strTopics = topics.join(',')
  157. let data = this.qs.stringify({
  158. _csrf:csrf,
  159. topics:strTopics
  160. })
  161. this.Post(data,topics)
  162. $('#repo-topics1').children('span').remove()
  163. this.showInputValue = false
  164. this.showAddTopic = true
  165. this.showAddFlage = true
  166. }
  167. },
  168. addPostTopic(){
  169. if(this.showAddFlage){
  170. this.arrayTopics.pop()
  171. let topics = this.arrayTopics
  172. let strTopics = topics.join(',')
  173. let data = this.qs.stringify({
  174. _csrf:csrf,
  175. topics:strTopics
  176. })
  177. this.Post(data,topics)
  178. if(this.arrayTopics.length===0){
  179. console.log("add postTopic")
  180. $('#repo-topics1').append('<span class="no-description text-italic">暂无标签</span>')
  181. }else{
  182. $('#repo-topics1').children('span').remove()
  183. }
  184. }
  185. else if(!this.showAddFlage){
  186. let topic = this.input
  187. this.arrayTopics.push(topic)
  188. let topics = this.arrayTopics
  189. let strTopics = topics.join(',')
  190. let data = this.qs.stringify({
  191. _csrf:csrf,
  192. topics:strTopics
  193. })
  194. this.Post(data,topics)
  195. $('#repo-topics1').children('span').remove()
  196. }
  197. this.showAddFlage = !this.showAddFlage
  198. },
  199. initTopics(){
  200. const mgrBtn = $('#manage_topic');
  201. const editDiv = $('#topic_edit');
  202. mgrBtn.on('click', (e) => {
  203. // viewDiv.hide();
  204. editDiv.css('display', ''); // show Semantic UI Grid
  205. this.input = ''
  206. if (this.input === ''){
  207. this.array = this.arrayTopics
  208. let data = []
  209. this.showInitTopic = []
  210. this.array.forEach((element,index) => {
  211. let item = {}
  212. item.topic_name = element
  213. data.push(item)
  214. this.showInitTopic.push(true)
  215. });
  216. this.array = data
  217. this.showInputValue = false
  218. this.showSearchTopic = true
  219. }
  220. stopPropagation(e);
  221. });
  222. $(document).bind('click',function(){
  223. editDiv.css('display','none');
  224. })
  225. editDiv.click(function(e){
  226. stopPropagation(e);
  227. })
  228. function stopPropagation(e) {
  229. var ev = e || window.event;
  230. if (ev.stopPropagation) {
  231. ev.stopPropagation();
  232. }
  233. else if (window.event) {
  234. window.event.cancelBubble = true;//兼容IE
  235. }
  236. }
  237. }
  238. },
  239. computed:{
  240. },
  241. watch: {
  242. input(newValue){
  243. if (newValue === ''){
  244. this.array = this.arrayTopics
  245. let data = []
  246. this.showInitTopic = []
  247. this.array.forEach((element,index) => {
  248. let item = {}
  249. item.topic_name = element
  250. data.push(item)
  251. this.showInitTopic.push(true)
  252. });
  253. this.array = data
  254. this.showInputValue = false
  255. this.showSearchTopic = true
  256. }
  257. }
  258. },
  259. mounted() {
  260. const context = this
  261. this.postUrl = `${window.location.pathname}/topics`;
  262. $('#repo-topics1').children('a').each(function(){
  263. context.arrayTopics.push($(this).text())
  264. });
  265. if(this.arrayTopics.length===0){
  266. $('#repo-topics1').append('<span class="no-description text-italic">暂无标签</span>')
  267. }
  268. this.changeValue()
  269. } ,
  270. created(){
  271. this.initTopics();
  272. this.input=''
  273. }
  274. };
  275. </script>
  276. <style scoped>
  277. .input-search {
  278. width: 100%;
  279. display: -webkit-box;
  280. display: -ms-flexbox;
  281. display: flex;
  282. min-width: 10rem;
  283. white-space: nowrap;
  284. font-size: 1rem;
  285. position: relative;
  286. display: inline-block;
  287. color: rgba(0,0,0,0.8);
  288. padding: 8px;
  289. }
  290. /deep/ .el-input__inner{
  291. border-color: #409eff;
  292. }
  293. .scrolling-menu{
  294. border-top: none !important;
  295. padding-top: 0 !important;
  296. padding-bottom: 0 !important;
  297. display: block;
  298. position: static;
  299. overflow-y: auto;
  300. border: none;
  301. -webkit-box-shadow: none !important;
  302. box-shadow: none !important;
  303. border-radius: 0 !important;
  304. margin: 0 !important;
  305. min-width: 100% !important;
  306. width: auto !important;
  307. border-top: 1px solid rgba(34,36,38,0.15);
  308. }
  309. .item-text{
  310. border-top: none;
  311. padding-right: calc(1.14285714rem + 17px ) !important;
  312. line-height: 1.333;
  313. padding-top: 0.7142857rem !important;
  314. padding-bottom: 0.7142857rem !important;
  315. position: relative;
  316. cursor: pointer;
  317. display: block;
  318. border: none;
  319. height: auto;
  320. text-align: left;
  321. border-top: none;
  322. line-height: 1em;
  323. color: rgba(0,0,0,0.87);
  324. padding: 0.78571429rem 1.14285714rem !important;
  325. font-size: 1rem;
  326. text-transform: none;
  327. font-weight: normal;
  328. -webkit-box-shadow: none;
  329. box-shadow: none;
  330. -webkit-touch-callout: none;
  331. display: -webkit-box;
  332. display: -ms-flexbox;
  333. display: flex;
  334. -webkit-box-align: center;
  335. -ms-flex-align: center;
  336. align-items: center;
  337. display: -webkit-box !important;
  338. display: -ms-flexbox !important;
  339. display: flex !important;
  340. }
  341. .icon-wrapper{
  342. text-align: left;
  343. width: 24px;
  344. height: 20px;
  345. -ms-flex-negative: 0;
  346. flex-shrink: 0;
  347. }
  348. .text{
  349. max-width: 80%;
  350. overflow: hidden;
  351. text-overflow: ellipsis;
  352. white-space: nowrap;
  353. font-size: 12px;
  354. font-weight: 400;
  355. color: #40485b;
  356. }
  357. .addition{
  358. background: #f6f6f6;
  359. }
  360. .user-add-label-text{
  361. max-width: 80%;
  362. overflow: hidden;
  363. text-overflow: ellipsis;
  364. white-space: nowrap;
  365. margin: 0 4px;
  366. }
  367. </style>