Index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. <template>
  2. <div class="hello" @keydown.ctrl.83.prevent="save" @keydown.meta.83.prevent="save">
  3. <Header> </Header>
  4. <el-container class="container-narrow">
  5. <el-row class="masthead">
  6. <el-form :inline="true" class="demo-form-inline" size="small">
  7. <el-form-item :label="$t('title')+' : '">
  8. <el-input placeholder="" v-model="title"></el-input>
  9. </el-form-item>
  10. <el-form-item :label="$t('catalog')+' : '" >
  11. <el-select :placeholder="$t('optional')" class="cat" v-model="cat_id">
  12. <el-option v-if="belong_to_catalogs" v-for="cat in belong_to_catalogs " :key="cat.cat_name" :label="cat.cat_name" :value="cat.cat_id"></el-option>
  13. </el-select>
  14. </el-form-item>
  15. <el-form-item :label="$t('s_number')+' : '">
  16. <el-input :placeholder="$t('optional')" class="num" v-model="s_number"></el-input>
  17. </el-form-item>
  18. <el-form-item label="" >
  19. <el-button type="text" @click="ShowHistoryVersion">{{$t('history_version')}}</el-button>
  20. </el-form-item>
  21. <el-form-item class="pull-right">
  22. <el-dropdown @command="dropdown_callback" split-button type="primary" size="medium" trigger="click" @click="save">
  23. {{$t('save')}}
  24. <el-dropdown-menu slot="dropdown">
  25. <el-dropdown-item :command="save_to_template">{{$t('save_to_templ')}}</el-dropdown-item>
  26. <!-- <el-dropdown-item>保存前添加注释</el-dropdown-item> -->
  27. </el-dropdown-menu>
  28. </el-dropdown>
  29. <el-button type="" size="medium" @click="goback">{{$t('goback')}}</el-button>
  30. </el-form-item>
  31. </el-form>
  32. <el-row class="fun-btn-group">
  33. <el-button type="" size="medium" @click="insert_api_template">{{$t('insert_apidoc_template')}}</el-button>
  34. <el-button type="" size="medium" @click="insert_database_template">{{$t('insert_database_doc_template')}}</el-button>
  35. <el-button type="" size="medium" @click.native="ShowTemplateList">{{$t('more_templ')}}</el-button>
  36. <el-dropdown split-button type="" style="margin-left:100px;" size="medium" trigger="hover" >
  37. {{$t('json_tools')}}
  38. <el-dropdown-menu slot="dropdown">
  39. <el-dropdown-item @click.native="ShowJsonToTable">{{$t('json_to_table')}}</el-dropdown-item>
  40. <el-dropdown-item @click.native="ShowJsonBeautify">{{$t('beautify_json')}}</el-dropdown-item>
  41. </el-dropdown-menu>
  42. </el-dropdown>
  43. <el-button type="" size="medium" @click="ShowRunApi">{{$t('http_test_api')}}</el-button>
  44. <el-badge :value="attachment_count" class="item">
  45. <el-button type="" size="medium" @click="ShowAttachment">{{$t('attachment')}}</el-button>
  46. </el-badge>
  47. </el-row>
  48. <Editormd v-bind:content="content" v-if="content" ref="Editormd" type="editor" ></Editormd>
  49. </el-row>
  50. <!-- 更多模板 -->
  51. <TemplateList :callback="insertValue" ref="TemplateList"></TemplateList>
  52. <!-- 历史版本 -->
  53. <HistoryVersion :callback="insertValue" :is_show_recover_btn="true" ref="HistoryVersion"></HistoryVersion>
  54. <!-- Json转表格 组件 -->
  55. <JsonToTable :callback="insertValue" ref="JsonToTable" ></JsonToTable>
  56. <!-- Json格式化 -->
  57. <JsonBeautify :callback="insertValue" ref="JsonBeautify"></JsonBeautify>
  58. <!-- 附件列表 -->
  59. <AttachmentList :callback="insertValue" :item_id="item_id" :manage="true" :page_id="page_id" ref="AttachmentList"></AttachmentList>
  60. </el-container>
  61. <Footer> </Footer>
  62. <div class=""></div>
  63. <!-- 模板存放的地方 -->
  64. <div id="api-doc-templ" ref="api_doc_templ" style="display:none">
  65. **简要描述:**
  66. - 用户注册接口
  67. **请求URL:**
  68. - ` http://xx.com/api/user/register `
  69. **请求方式:**
  70. - POST
  71. **参数:**
  72. |参数名|必选|类型|说明|
  73. |:---- |:---|:----- |----- |
  74. |username |是 |string |用户名 |
  75. |password |是 |string | 密码 |
  76. |name |否 |string | 昵称 |
  77. **返回示例**
  78. ```
  79. {
  80. "error_code": 0,
  81. "data": {
  82. "uid": "1",
  83. "username": "12154545",
  84. "name": "吴系挂",
  85. "groupid": 2 ,
  86. "reg_time": "1436864169",
  87. "last_login_time": "0",
  88. }
  89. }
  90. ```
  91. **返回参数说明**
  92. |参数名|类型|说明|
  93. |:----- |:-----|----- |
  94. |groupid |int |用户组id,1:超级管理员;2:普通用户 |
  95. **备注**
  96. - 更多返回错误代码请看首页的错误代码描述
  97. </div>
  98. <div id="database-doc-templ" ref="database_doc_templ" style="display:none">
  99. - 用户表,储存用户信息
  100. |字段|类型|空|默认|注释|
  101. |:---- |:------- |:--- |-- -|------ |
  102. |uid |int(10) |否 | | |
  103. |username |varchar(20) |否 | | 用户名 |
  104. |password |varchar(50) |否 | | 密码 |
  105. |name |varchar(15) |是 | | 昵称 |
  106. |reg_time |int(11) |否 | 0 | 注册时间 |
  107. - 备注:无
  108. </div>
  109. </div>
  110. </template>
  111. <style scoped>
  112. .container-narrow{
  113. margin: 0 auto;
  114. max-width: 90%;
  115. }
  116. .masthead{
  117. width: 100%;
  118. margin-top: 5px;
  119. }
  120. .cat{
  121. width: 200px;
  122. }
  123. .num{
  124. width: 60px;
  125. }
  126. .fun-btn-group{
  127. margin-top: 15px;
  128. margin-bottom: 15px;
  129. }
  130. </style>
  131. <script>
  132. import Editormd from '@/components/common/Editormd'
  133. import JsonToTable from '@/components/common/JsonToTable'
  134. import JsonBeautify from '@/components/common/JsonBeautify'
  135. import TemplateList from '@/components/page/edit/TemplateList'
  136. import HistoryVersion from '@/components/page/edit/HistoryVersion'
  137. import AttachmentList from '@/components/page/edit/AttachmentList'
  138. export default {
  139. data () {
  140. return {
  141. currentDate: new Date(),
  142. itemList:{},
  143. content:"",
  144. title:"",
  145. item_id:0,
  146. cat_id:'',
  147. s_number:'',
  148. page_id:'',
  149. copy_page_id:'',
  150. attachment_count:'',
  151. };
  152. },
  153. computed: {
  154. //新建/编辑页面时供用户选择的归属目录列表
  155. belong_to_catalogs:function(){
  156. var Info = this.catalogs.slice(0);
  157. var cat_array = [] ;
  158. for (var i = 0; i < Info.length; i++) {
  159. cat_array.push(Info[i]);
  160. var sub = Info[i]['sub'] ;
  161. if (sub.length > 0 ) {
  162. for (var j = 0; j < sub.length; j++) {
  163. cat_array.push( {
  164. "cat_id":sub[j]['cat_id'] ,
  165. "cat_name":Info[i]['cat_name']+' / ' + sub[j]['cat_name']
  166. });
  167. var sub_sub = sub[j]['sub'] ;
  168. if (sub_sub.length > 0 ) {
  169. for (var k = 0; k < sub_sub.length; k++) {
  170. cat_array.push( {
  171. "cat_id":sub_sub[k]['cat_id'] ,
  172. "cat_name":Info[i]['cat_name']+' / ' + sub[j]['cat_name']+' / ' + sub_sub[k]['cat_name']
  173. });
  174. };
  175. };
  176. };
  177. };
  178. };
  179. var no_cat = {"cat_id":'' ,"cat_name":this.$t("none")} ;
  180. cat_array.unshift(no_cat);
  181. return cat_array;
  182. }
  183. },
  184. components:{
  185. Editormd,
  186. JsonToTable,
  187. JsonBeautify,
  188. TemplateList,
  189. HistoryVersion,
  190. AttachmentList
  191. },
  192. methods:{
  193. //获取页面内容
  194. get_page_content(page_id){
  195. if (!page_id) {
  196. var page_id = this.page_id ;
  197. };
  198. var that = this ;
  199. var url = DocConfig.server+'/api/page/info';
  200. var params = new URLSearchParams();
  201. params.append('page_id', page_id );
  202. that.axios.post(url, params)
  203. .then(function (response) {
  204. if (response.data.error_code === 0 ) {
  205. //that.$message.success("加载成功");
  206. that.content = response.data.data.page_content ;
  207. setTimeout(function(){
  208. that.insertValue(that.content ,1) ;
  209. },500);
  210. setTimeout(function(){
  211. //如果长度大于3000,则关闭预览
  212. if (that.content.length > 3000) {
  213. that.editor_unwatch();
  214. }else{
  215. that.editor_watch();
  216. }
  217. },1000);
  218. that.title = response.data.data.page_title ;
  219. that.item_id = response.data.data.item_id ;
  220. that.s_number = response.data.data.s_number ;
  221. that.attachment_count = response.data.data.attachment_count > 0 ? "..." :'' ;
  222. }else{
  223. that.$alert(response.data.error_message);
  224. }
  225. })
  226. .catch(function (error) {
  227. console.log(error);
  228. });
  229. },
  230. //获取所有目录
  231. get_catalog(item_id){
  232. var that = this ;
  233. var url = DocConfig.server+'/api/catalog/catListGroup';
  234. var params = new URLSearchParams();
  235. params.append('item_id', item_id);
  236. that.axios.post(url, params)
  237. .then(function (response) {
  238. if (response.data.error_code === 0 ) {
  239. var Info = response.data.data ;
  240. that.catalogs = Info;
  241. that.get_default_cat();
  242. }else{
  243. that.$alert(response.data.error_message);
  244. }
  245. })
  246. .catch(function (error) {
  247. console.log(error);
  248. });
  249. },
  250. //获取默认该选中的目录
  251. get_default_cat(){
  252. var that = this ;
  253. var url = DocConfig.server+'/api/catalog/getDefaultCat';
  254. var params = new URLSearchParams();
  255. params.append('page_id', this.page_id);
  256. params.append('item_id', that.$route.params.item_id);
  257. params.append('copy_page_id', this.copy_page_id);
  258. that.axios.post(url, params)
  259. .then(function (response) {
  260. if (response.data.error_code === 0 ) {
  261. //that.$message.success("加载成功");
  262. var json = response.data.data ;
  263. that.cat_id = json.default_cat_id ;
  264. }else{
  265. that.$alert(response.data.error_message);
  266. }
  267. });
  268. },
  269. //插入数据到编辑器中。插入到光标处。如果参数is_cover为真,则清空后再插入(即覆盖)。
  270. insertValue(value,is_cover){
  271. if (value) {
  272. let childRef = this.$refs.Editormd ;//获取子组件
  273. if (is_cover) {
  274. // 清空
  275. childRef.clear();
  276. };
  277. childRef.insertValue(value) ; //调用子组件的方法
  278. };
  279. },
  280. //插入api模板
  281. insert_api_template(){
  282. this.insertValue(this.$refs.api_doc_templ.innerHTML ) ;
  283. },
  284. //插入数据字典模板
  285. insert_database_template(){
  286. this.insertValue(this.$refs.database_doc_templ.innerHTML ) ;
  287. },
  288. //关闭预览
  289. editor_unwatch(){
  290. let childRef = this.$refs.Editormd ;//获取子组件
  291. childRef.editor_unwatch();
  292. if ( sessionStorage.getItem("page_id_unwatch_"+this.page_id) ) {
  293. }else{
  294. this.$alert("检测到本页面内容比较多,showdoc暂时关闭了html实时预览功能,以防止过多内容造成页面卡顿。你可以在编辑栏中找到预览按钮进行手动打开。");
  295. sessionStorage.setItem("page_id_unwatch_"+this.page_id,1)
  296. }
  297. },
  298. //
  299. editor_watch(){
  300. let childRef = this.$refs.Editormd ;//获取子组件
  301. childRef.editor_watch();
  302. },
  303. //json转参数表格
  304. ShowJsonToTable(){
  305. let childRef = this.$refs.JsonToTable ;//获取子组件
  306. childRef.dialogFormVisible = true ;
  307. },
  308. //json格式化
  309. ShowJsonBeautify(){
  310. let childRef = this.$refs.JsonBeautify ;//获取子组件
  311. childRef.dialogFormVisible = true ;
  312. },
  313. ShowRunApi(){
  314. window.open('http://runapi.showdoc.cc/');
  315. },
  316. //更多模板、模板列表
  317. ShowTemplateList(){
  318. let childRef = this.$refs.TemplateList ;//获取子组件
  319. childRef.show() ;
  320. },
  321. //展示历史版本
  322. ShowHistoryVersion(){
  323. let childRef = this.$refs.HistoryVersion ;//获取子组件
  324. childRef.show() ;
  325. },
  326. save(){
  327. var that = this ;
  328. var loading = that.$loading();
  329. let childRef = this.$refs.Editormd ;
  330. var content = childRef.getMarkdown() ;
  331. var cat_id = this.cat_id ;
  332. var item_id = that.$route.params.item_id ;
  333. var page_id = that.$route.params.page_id ;
  334. var url = DocConfig.server+'/api/page/save';
  335. var params = new URLSearchParams();
  336. params.append('page_id', page_id);
  337. params.append('item_id', item_id);
  338. params.append('s_number', that.s_number);
  339. params.append('page_title', that.title);
  340. params.append('page_content', encodeURIComponent(content));
  341. params.append('is_urlencode', 1);
  342. params.append('cat_id', cat_id);
  343. that.axios.post(url, params)
  344. .then(function (response) {
  345. loading.close();
  346. if (response.data.error_code === 0 ) {
  347. that.$message({
  348. showClose: true,
  349. message: that.$t("save_success"),
  350. type: 'success'
  351. });
  352. localStorage.removeItem("page_content");
  353. if (page_id <= 0 ) {
  354. that.$router.push({path:'/page/edit/'+item_id+'/'+response.data.data.page_id}) ;
  355. that.page_id = response.data.data.page_id ;
  356. };
  357. }else{
  358. that.$alert(response.data.error_message);
  359. }
  360. });
  361. //设置一个最长关闭时间
  362. setTimeout(() => {
  363. loading.close();
  364. }, 20000);
  365. },
  366. goback(){
  367. localStorage.removeItem("page_content");
  368. var url = '/'+this.$route.params.item_id;
  369. this.$router.push({path:url,query:{page_id:this.$route.params.page_id}}) ;
  370. },
  371. dropdown_callback(data){
  372. if (data) {
  373. data();
  374. };
  375. },
  376. //另存为模板
  377. save_to_template(){
  378. var that = this ;
  379. let childRef = this.$refs.Editormd ;
  380. var content = childRef.getMarkdown() ;
  381. this.$prompt(that.$t("save_templ_title"), ' ', {
  382. }).then(function(data){
  383. var url = DocConfig.server+'/api/template/save';
  384. var params = new URLSearchParams();
  385. params.append('template_title', data.value);
  386. params.append('template_content', content);
  387. that.axios.post(url, params)
  388. .then(function (response) {
  389. if (response.data.error_code === 0 ) {
  390. that.$alert(that.$t("save_templ_text"));
  391. }else{
  392. that.$alert(response.data.error_message);
  393. }
  394. });
  395. });
  396. },
  397. //附件
  398. ShowAttachment(){
  399. let childRef = this.$refs.AttachmentList ;//获取子组件
  400. childRef.show() ;
  401. },
  402. /** 粘贴上传图片 **/
  403. upload_paste_img(e){
  404. var that = this;
  405. var url = DocConfig.server+'/api/page/uploadImg';
  406. var clipboard = e.clipboardData;
  407. for (var i = 0, len = clipboard.items.length; i < len; i++) {
  408. if (clipboard.items[i].kind == 'file' || clipboard.items[i].type.indexOf('image') > -1) {
  409. var imageFile = clipboard.items[i].getAsFile();
  410. var form = new FormData;
  411. form.append('t', 'ajax-uploadpic');
  412. form.append('editormd-image-file', imageFile);
  413. var loading = '';
  414. var callback = function(type, data) {
  415. type = type || 'before';
  416. switch (type) {
  417. // 开始上传
  418. case 'before':
  419. loading = that.$loading();
  420. break;
  421. // 服务器返回错误
  422. case 'error':
  423. loading.close();
  424. that.$alert('图片上传失败');
  425. break;
  426. // 上传成功
  427. case 'success':
  428. loading.close();
  429. if (data.success == 1) {
  430. var value = '![](' + data.url + ')';
  431. that.insertValue(value);
  432. } else {
  433. that.$alert(data.message);
  434. }
  435. break;
  436. }
  437. };
  438. $.ajax({
  439. url: url,
  440. type: "POST",
  441. dataType: "json",
  442. data: form,
  443. processData: false,
  444. contentType: false,
  445. beforeSend: function() {
  446. callback('before');
  447. },
  448. error: function() {
  449. callback('error');
  450. },
  451. success: function(data) {
  452. callback('success', data);
  453. }
  454. })
  455. e.preventDefault();
  456. }
  457. }
  458. }
  459. },
  460. mounted () {
  461. var that = this ;
  462. this.page_id = this.$route.params.page_id ;
  463. this.copy_page_id = this.$route.query.copy_page_id ? this.$route.query.copy_page_id : '' ;
  464. if (this.copy_page_id > 0 ) {
  465. this.get_page_content(this.copy_page_id);
  466. }
  467. else if (this.page_id > 0 ) {
  468. this.get_page_content(this.page_id);
  469. }else{
  470. this.item_id = this.$route.params.item_id ;
  471. this.content = this.$t("welcome_use_showdoc") ;
  472. }
  473. this.get_catalog(this.$route.params.item_id);
  474. /** 监听粘贴上传图片 **/
  475. document.addEventListener('paste', this.upload_paste_img);
  476. },
  477. beforeDestroy(){
  478. //解除对粘贴上传图片的监听
  479. document.removeEventListener('paste', this.upload_paste_img);
  480. }
  481. }
  482. </script>