Index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. <template>
  2. <div class="hello">
  3. <Header></Header>
  4. <el-container class="container-narrow">
  5. <el-row class="masthead">
  6. <div class="logo-title">
  7. <h2 class="muted">
  8. <img src="static/logo/b_64.png" style="width:50px;height:50px;margin-bottom:-10px;" alt />ShowDoc
  9. </h2>
  10. </div>
  11. <div class="header-btn-group pull-right">
  12. <el-tooltip class="item" effect="dark" :content="$t('feedback')" placement="top">
  13. <router-link to>
  14. <i @click="feedback" class="el-icon-phone-outline"></i>
  15. </router-link>
  16. </el-tooltip>
  17. <el-tooltip
  18. v-if="lang =='zh-cn'"
  19. class="item"
  20. effect="dark"
  21. content="客户端"
  22. placement="top"
  23. >
  24. <a target="_blank" href="https://www.showdoc.cc/clients">
  25. <i class="el-icon-mobile-phone"></i>
  26. </a>
  27. </el-tooltip>
  28. <el-tooltip v-if="lang =='zh-cn'" class="item" effect="dark" content="接口开发调试工具RunApi" placement="top">
  29. <a target="_blank" href="https://www.showdoc.cc/runapi">
  30. <i class="el-icon-connection"></i>
  31. </a>
  32. </el-tooltip>
  33. <el-tooltip class="item" effect="dark" :content="$t('team_mamage')" placement="top">
  34. <router-link to="/team/index">
  35. <i class="el-icon-s-flag"></i>
  36. </router-link>
  37. </el-tooltip>
  38. <el-tooltip
  39. v-if="isAdmin"
  40. class="item"
  41. effect="dark"
  42. :content="$t('background')"
  43. placement="top"
  44. >
  45. <router-link to="/admin/index">
  46. <i class="el-icon-s-tools"></i>
  47. </router-link>
  48. </el-tooltip>&nbsp;&nbsp;
  49. <el-tooltip class="item" effect="dark" :content="$t('more')" placement="top">
  50. <el-dropdown @command="dropdown_callback" trigger="click">
  51. <span class="el-dropdown-link">
  52. <i class="el-icon-caret-bottom el-icon--right"></i>
  53. </span>
  54. <el-dropdown-menu slot="dropdown">
  55. <el-dropdown-item>
  56. <router-link to="/user/setting">{{$t("personal_setting")}}</router-link>
  57. </el-dropdown-item>
  58. <el-dropdown-item :command="logout">{{$t("logout")}}</el-dropdown-item>
  59. </el-dropdown-menu>
  60. </el-dropdown>
  61. </el-tooltip>
  62. </div>
  63. </el-row>
  64. </el-container>
  65. <el-container class="container-narrow">
  66. <div class="container-thumbnails">
  67. <div class="search-box-div" v-if="itemList.length > 9">
  68. <div class="search-box el-input el-input--prefix">
  69. <input
  70. autocomplete="off"
  71. type="text"
  72. rows="2"
  73. validateevent="true"
  74. class="el-input__inner"
  75. v-model="keyword"
  76. />
  77. <span class="el-input__prefix">
  78. <i class="el-input__icon el-icon-search"></i>
  79. </span>
  80. </div>
  81. </div>
  82. <ul class="thumbnails" id="item-list" v-if="itemListByKeyword">
  83. <draggable
  84. v-model="itemListByKeyword"
  85. tag="span"
  86. group="item"
  87. @end="endMove"
  88. ghostClass="sortable-chosen"
  89. >
  90. <li
  91. class="text-center"
  92. v-for="item in itemListByKeyword"
  93. v-dragging="{ item: item, list: itemListByKeyword, group: 'item' }"
  94. :key="item.item_id"
  95. >
  96. <router-link
  97. class="thumbnail item-thumbnail"
  98. :to="'/' + (item.item_domain ? item.item_domain:item.item_id )"
  99. title
  100. >
  101. <!-- 自己创建的话显示项目设置按钮 -->
  102. <span
  103. class="item-setting"
  104. @click.prevent="click_item_setting(item.item_id)"
  105. :title="$t('item_setting')"
  106. v-if="item.creator"
  107. >
  108. <i class="el-icon-setting"></i>
  109. </span>
  110. <!-- 如果是加入的项目的话,这里显示退出按钮 -->
  111. <span
  112. class="item-exit"
  113. @click.prevent="click_item_exit(item.item_id)"
  114. :title="$t('item_exit')"
  115. v-if="! item.creator"
  116. >
  117. <i class="el-icon-close"></i>
  118. </span>
  119. <p class="my-item">{{item.item_name}}</p>
  120. <!-- 如果是加密项目的话,这里显示一个加密图标 -->
  121. <span class="item-private" v-if="item.is_private">
  122. <el-tooltip
  123. class="item"
  124. effect="dark"
  125. :content="$t('private_tips')"
  126. placement="right"
  127. >
  128. <i class="el-icon-lock"></i>
  129. </el-tooltip>
  130. </span>
  131. </router-link>
  132. </li>
  133. </draggable>
  134. <li class="text-center">
  135. <router-link class="thumbnail item-thumbnail" to="/item/add" title>
  136. <p class="my-item">
  137. {{$t('new_item')}}
  138. <i class="el-icon-plus"></i>
  139. </p>
  140. </router-link>
  141. </li>
  142. </ul>
  143. </div>
  144. </el-container>
  145. <Footer></Footer>
  146. </div>
  147. </template>
  148. <style scoped>
  149. .container-narrow {
  150. margin: 0 auto;
  151. max-width: 930px;
  152. }
  153. .masthead {
  154. width: 100%;
  155. margin-top: 30px;
  156. }
  157. .header-btn-group {
  158. margin-top: -38px;
  159. font-size: 18px;
  160. }
  161. .header-btn-group a {
  162. color: #333;
  163. margin-left: 25px;
  164. }
  165. .el-dropdown {
  166. font-size: 18px;
  167. }
  168. .el-dropdown-link,
  169. a {
  170. color: #333;
  171. }
  172. .logo-title {
  173. margin-left: 0px;
  174. }
  175. .container-thumbnails {
  176. margin-top: 30px;
  177. max-width: 1000px;
  178. }
  179. .my-item {
  180. margin: 40px 5px;
  181. }
  182. .thumbnails li {
  183. float: left;
  184. margin-bottom: 20px;
  185. margin-left: 20px;
  186. }
  187. .thumbnails li a {
  188. color: #444;
  189. font-weight: bold;
  190. height: 100px;
  191. width: 180px;
  192. }
  193. .thumbnails li a:hover,
  194. .thumbnails li a:focus {
  195. border-color: #f2f5e9;
  196. -webkit-box-shadow: none;
  197. box-shadow: none;
  198. text-decoration: none;
  199. background-color: #f2f5e9;
  200. }
  201. .thumbnail {
  202. display: block;
  203. padding: 4px;
  204. line-height: 20px;
  205. border: 1px solid #ddd;
  206. -webkit-border-radius: 4px;
  207. -moz-border-radius: 4px;
  208. border-radius: 4px;
  209. -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
  210. -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
  211. box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
  212. -webkit-transition: all 0.2s ease-in-out;
  213. -moz-transition: all 0.2s ease-in-out;
  214. -o-transition: all 0.2s ease-in-out;
  215. transition: all 0.2s ease-in-out;
  216. list-style: none;
  217. background-color: #ffffff;
  218. }
  219. .item-setting {
  220. float: right;
  221. margin-right: 15px;
  222. margin-top: 5px;
  223. display: none;
  224. }
  225. .item-exit {
  226. float: right;
  227. margin-right: 5px;
  228. margin-top: 5px;
  229. display: none;
  230. }
  231. .item-private {
  232. float: right;
  233. margin-right: 15px;
  234. margin-top: -20px;
  235. display: none;
  236. cursor: default;
  237. }
  238. .thumbnails li a i {
  239. color: #777;
  240. font-weight: bold;
  241. margin-left: 5px;
  242. }
  243. .item-thumbnail:hover .item-setting {
  244. display: block;
  245. }
  246. .item-thumbnail:hover .item-exit {
  247. display: block;
  248. }
  249. .item-thumbnail:hover .item-private {
  250. display: block;
  251. }
  252. .search-box-div {
  253. width: 190px;
  254. margin-left: 60px;
  255. }
  256. .sortable-chosen .item-thumbnail {
  257. color: #ffffff;
  258. background-color: #ffffff;
  259. }
  260. </style>
  261. <script>
  262. import draggable from 'vuedraggable'
  263. if (typeof window !== 'undefined') {
  264. var $s = require('scriptjs')
  265. }
  266. export default {
  267. components: {
  268. draggable
  269. },
  270. data() {
  271. return {
  272. currentDate: new Date(),
  273. itemList: {},
  274. isAdmin: false,
  275. keyword: '',
  276. lang: ''
  277. }
  278. },
  279. computed: {
  280. itemListByKeyword: function() {
  281. if (!this.keyword) {
  282. return this.itemList
  283. }
  284. let itemListByKeyword = []
  285. for (var i = 0; i < this.itemList.length; i++) {
  286. if (this.itemList[i]['item_name'].indexOf(this.keyword) > -1) {
  287. itemListByKeyword.push(this.itemList[i])
  288. }
  289. }
  290. return itemListByKeyword
  291. }
  292. },
  293. methods: {
  294. get_item_list() {
  295. var that = this
  296. var url = DocConfig.server + '/api/item/myList'
  297. var params = new URLSearchParams()
  298. that.axios.get(url, params).then(function(response) {
  299. if (response.data.error_code === 0) {
  300. // that.$message.success("加载成功");
  301. var json = response.data.data
  302. that.itemList = json
  303. // that.bind_item_even();
  304. } else {
  305. // that.$alert(response.data.error_message);
  306. }
  307. })
  308. },
  309. feedback() {
  310. if (DocConfig.lang == 'en') {
  311. window.open('https://github.com/star7th/showdoc/issues')
  312. } else {
  313. var msg =
  314. '你正在使用免费开源版showdoc,如有问题或者建议,请到github提issue:'
  315. msg +=
  316. "<a href='https://github.com/star7th/showdoc/issues' target='_blank'>https://github.com/star7th/showdoc/issues</a><br>"
  317. msg +=
  318. '如果你觉得showdoc好用,不妨给开源项目点一个star。良好的关注度和参与度有助于开源项目的长远发展。'
  319. this.$alert(msg, {
  320. dangerouslyUseHTMLString: true
  321. })
  322. }
  323. },
  324. item_top_class(top) {
  325. if (top) {
  326. return 'el-icon-arrow-down'
  327. }
  328. return 'el-icon-arrow-up'
  329. },
  330. bind_item_even() {
  331. // 这里偷个懒,直接用jquery来操作DOM。因为老版本的代码就是基于jquery的,所以复制过来稍微改下
  332. $s(['static/jquery.min.js'], () => {
  333. // 当鼠标放在项目上时将浮现设置和置顶图标
  334. $('.item-thumbnail').mouseover(function() {
  335. $(this)
  336. .find('.item-setting')
  337. .show()
  338. // $(this).find(".item-top").show();
  339. // $(this).find(".item-down").show();
  340. })
  341. // 当鼠标离开项目上时将隐藏设置和置顶图标
  342. $('.item-thumbnail').mouseout(function() {
  343. $(this)
  344. .find('.item-setting')
  345. .hide()
  346. $(this)
  347. .find('.item-top')
  348. .hide()
  349. $(this)
  350. .find('.item-down')
  351. .hide()
  352. })
  353. })
  354. },
  355. // 进入项目设置页
  356. click_item_setting(item_id) {
  357. this.$router.push({ path: '/item/setting/' + item_id })
  358. },
  359. click_item_exit(item_id) {
  360. var that = this
  361. this.$confirm(that.$t('confirm_exit_item'), ' ', {
  362. confirmButtonText: that.$t('confirm'),
  363. cancelButtonText: that.$t('cancel'),
  364. type: 'warning'
  365. }).then(() => {
  366. var url = DocConfig.server + '/api/item/exitItem'
  367. var params = new URLSearchParams()
  368. params.append('item_id', item_id)
  369. that.axios.post(url, params).then(function(response) {
  370. if (response.data.error_code === 0) {
  371. window.location.reload()
  372. } else {
  373. that.$alert(response.data.error_message)
  374. }
  375. })
  376. })
  377. },
  378. logout() {
  379. var that = this
  380. var url = DocConfig.server + '/api/user/logout'
  381. var params = new URLSearchParams()
  382. that.axios.get(url, params).then(function(response) {
  383. if (response.data.error_code === 0) {
  384. that.$router.push({
  385. path: '/'
  386. })
  387. } else {
  388. that.$alert(response.data.error_message)
  389. }
  390. })
  391. },
  392. user_info() {
  393. var that = this
  394. this.get_user_info(function(response) {
  395. if (response.data.error_code === 0) {
  396. if (response.data.data.groupid == 1) {
  397. that.isAdmin = true
  398. }
  399. }
  400. })
  401. },
  402. dropdown_callback(data) {
  403. if (data) {
  404. data()
  405. }
  406. },
  407. sort_item(data) {
  408. var that = this
  409. var url = DocConfig.server + '/api/item/sort'
  410. var params = new URLSearchParams()
  411. params.append('data', JSON.stringify(data))
  412. that.axios.post(url, params).then(function(response) {
  413. if (response.data.error_code === 0) {
  414. that.get_item_list()
  415. // window.location.reload();
  416. } else {
  417. that.$alert(response.data.error_message, '', {
  418. callback: function() {
  419. window.location.reload()
  420. }
  421. })
  422. }
  423. })
  424. },
  425. exchangeArray(data, oldIndex, newIndex) {
  426. let tmp = data[oldIndex]
  427. data.splice(oldIndex, 1)
  428. data.splice(newIndex, 0, tmp)
  429. return data
  430. },
  431. endMove(evt) {
  432. let data = {}
  433. let list = this.exchangeArray(
  434. this.itemList,
  435. evt['oldIndex'],
  436. evt['newIndex']
  437. )
  438. this.itemList = []
  439. this.$nextTick(() => {
  440. this.itemList = list
  441. })
  442. for (var i = 0; i < list.length; i++) {
  443. let key = list[i]['item_id']
  444. data[key] = i + 1
  445. }
  446. this.sort_item(data)
  447. },
  448. script_cron() {
  449. var url = DocConfig.server + '/api/ScriptCron/run'
  450. this.axios.get(url)
  451. }
  452. },
  453. mounted() {
  454. this.get_item_list()
  455. this.user_info()
  456. this.lang = DocConfig.lang
  457. this.script_cron()
  458. },
  459. beforeDestroy() {
  460. this.$message.closeAll()
  461. }
  462. }
  463. </script>