1
0

writer.html 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="referrer" content="no-referrer">
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  7. <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
  8. <meta http-equiv="pragma" content="no-cache">
  9. <meta http-equiv="cache-control" content="no-cache">
  10. <meta http-equiv="expires" content="0">
  11. <title>webchat-公众号文章编辑</title>
  12. <link rel="shortcut icon" href="/favicon.ico" />
  13. <link rel="bookmark" href="/favicon.ico" />
  14. <link href="/ref/wangeditor5/editor.css" rel="stylesheet">
  15. <link href="/css/client/writer.css" rel="stylesheet" type="text/css" />
  16. <link rel="stylesheet" href="/css/common/common.css">
  17. <link rel="stylesheet" href="/css/client/chat.css">
  18. <link href="/ref/layui-v2.6.8/layui/css/layui.css" rel="stylesheet" type="text/css" />
  19. <script src="/ref/jquery/jquery-3.4.1.js" type="text/javascript"></script>
  20. <script src="/ref/layui-v2.6.8/layui/layui.js" type="text/javascript"></script>
  21. <script src="/ref/wangeditor5/editor.js"></script>
  22. <style>
  23. #public-account-select {
  24. position: relative;
  25. float: left;
  26. top: 10px;
  27. width: 200px;
  28. height: 40px;
  29. border-radius: 3px;
  30. border: 1px solid #e6e1e1;
  31. }
  32. #editor-container-box {
  33. min-height: 600px;
  34. height: auto;
  35. width: 700px;
  36. padding: 20px 80px 150px 80px;
  37. background-color: white;
  38. border: 0px;
  39. border-radius: 3px;
  40. margin-top: 130px;
  41. margin-bottom: 80px;
  42. box-shadow: 0px 0px 3px #d9d8d8;
  43. }
  44. .editor-footer {
  45. position: fixed;
  46. bottom: 0px;
  47. height: 60px;
  48. line-height: 60px;
  49. width: 860px;
  50. left: calc((100% - 860px)/2);
  51. background-color: #f6f8f9;
  52. }
  53. #toolbar-container {
  54. border: 0px;
  55. }
  56. #editor-header {
  57. position: relative;
  58. width: 100%;
  59. height: 60px;
  60. }
  61. #editor-title {
  62. line-height: 60px;
  63. font-size: 25px;
  64. text-align: left;
  65. width: 100%;
  66. border: 0px;
  67. padding: 12px;
  68. border-bottom: 1px solid whitesmoke;
  69. }
  70. #yipian-header {
  71. position: fixed;
  72. top: 0px;
  73. left: 0px;
  74. width: 100%;
  75. height: 60px;
  76. background-color: white;
  77. z-index: 999;
  78. }
  79. .editor-logo {
  80. position: absolute;
  81. left: 50px;
  82. height: 35px;
  83. top: 10px;
  84. }
  85. .common-login-user {
  86. width: 30px;
  87. height: 30px;
  88. border-radius: 40px;
  89. padding: 3px;
  90. border: 1px solid #f1f1f1;
  91. }
  92. .common-login-user {
  93. width: 30px; height: 30px; border-radius: 40px; padding: 3px; border: 1px solid #f1f1f1
  94. }
  95. .common-login-user:hover {
  96. cursor: pointer;
  97. }
  98. .editor-ext {
  99. position: relative;
  100. width: 100%;
  101. margin-top: 40px;
  102. display: block;
  103. }
  104. .editor-ext-title {
  105. text-align: left;
  106. font-size: 16px;
  107. line-height: 20px;
  108. margin-bottom: 20px;
  109. color: #353535;
  110. }
  111. .editor-ext-title2 {
  112. text-align: left;
  113. font-size: 14px;
  114. line-height: 20px;
  115. margin: 20px 0px 10px 0px;
  116. color: #b6b3b3;
  117. }
  118. .editor-cover-image-upload {
  119. float: left;
  120. position: relative;
  121. height: 90px;
  122. width: 212px;
  123. border: 2px dashed whitesmoke;
  124. overflow: hidden;
  125. color: #b1afaf;
  126. line-height: 90px;
  127. overflow: hidden;
  128. }
  129. .editor-cover-image-upload:hover {
  130. cursor: pointer;
  131. background-color: #faf9f9;
  132. }
  133. #editor-description {
  134. float: left;
  135. position: relative;
  136. height: 90px;
  137. width: 360px;
  138. margin-left: 20px;
  139. border: 1px solid whitesmoke;
  140. }
  141. #editor-description textarea {
  142. position: absolute;
  143. left: 2px;
  144. top: 2px;
  145. width: 340px;
  146. height: 75px;
  147. border: 0px;
  148. resize: none;
  149. padding: 5px;
  150. }
  151. #standalone-container{
  152. position: fixed;
  153. top: 60px;
  154. padding: 15px 0px;
  155. left: 0px;
  156. height: 40px;
  157. border: 0px;
  158. z-index: 999;
  159. width: 100%;
  160. background-color: #f6f8f9;
  161. }
  162. .editor-out-url {
  163. position: relative;
  164. width: 100%;
  165. height: 45px;
  166. line-height: 45px;
  167. border-radius: 3px;
  168. border: 1px solid whitesmoke;
  169. text-indent: 10px;
  170. }
  171. .editor-sign-box, #editor-path-id {
  172. position: relative;
  173. width: 100%;
  174. height: 45px;
  175. line-height: 45px;
  176. border-radius: 3px;
  177. border: 1px solid whitesmoke;
  178. }
  179. #editor-cover-image {
  180. position: absolute;
  181. left: 5px;
  182. top: 5px;
  183. height: 80px;
  184. width: 202px;
  185. display: none;
  186. }
  187. .editor-footer button {
  188. width: 100px;
  189. height: 35px;
  190. border: 1px solid whitesmoke;
  191. border-radius: 5px;
  192. color: #353535;
  193. background-color: white;
  194. font-weight: 400;
  195. }
  196. .editor-footer button:hover {
  197. cursor: pointer;
  198. opacity: 0.7;
  199. }
  200. .editor-plugin-module {
  201. position: relative;
  202. width: 760px;
  203. height: 40px;
  204. margin-top: 10px;
  205. }
  206. .editor-plugin-module button {
  207. background-color: #f7f7f7;
  208. border: 0px;
  209. height: 35px;
  210. float: left;
  211. padding: 0px 20px;
  212. }
  213. .editor-plugin-module button:hover {
  214. background-color: #ededed;
  215. }
  216. input:-moz-placeholder {
  217. color: #e5e5e5;
  218. }
  219. input:-moz-placeholder {
  220. color: #e5e5e5;
  221. }
  222. input:-moz-placeholder {
  223. color: #e5e5e5;
  224. }
  225. </style>
  226. <style>
  227. .w-e-bar {
  228. background-color: #f6f8f9;
  229. }
  230. </style>
  231. </head>
  232. <body style="overflow-x: hidden; background-color: #f6f8f9;">
  233. <center>
  234. <div id="yipian-header">
  235. <a href="/"><img src="/image/icon/writer-logo.png" class="editor-logo"></a>
  236. <img src="" id="author-photo" style="position: absolute; right: 50px; top: 10px; height: 40px; width: 40px; border-radius: 100%">
  237. </div>
  238. <div id="standalone-container">
  239. <div id="toolbar-container" style="background-color: transparent; width: 1200px;">
  240. </div>
  241. </div>
  242. <div id="editor-container-box">
  243. <div id="editor-header">
  244. <input id="editor-title" placeholder="请输入标题(5 - 50字)">
  245. </div>
  246. <div id="content" style="text-align: left; min-height: 500px; height: auto"></div>
  247. <div class="editor-ext">
  248. <div class="editor-ext-title">封面和摘要</div>
  249. <div class="editor-cover-image-upload" id="editor-cover-image-upload">
  250. <span id="editor-cover-image-upload-default">选择封面</span>
  251. <img src="" id="editor-cover-image">
  252. </div>
  253. <div id="editor-description">
  254. <textarea id="editor-description-input"
  255. placeholder="用于文章列表、分享等外显,帮助读者快速了解内容,如不填写则默认抓取文章前54字"></textarea>
  256. </div>
  257. <div style="clear: both"></div>
  258. </div>
  259. <div class="editor-ext">
  260. <div class="editor-ext-title">绑定公众号</div>
  261. <select id="public-account-select"></select>
  262. <div style="clear: both"></div>
  263. </div>
  264. <div class="editor-ext">
  265. <div class="editor-ext-title2">文章标签</div>
  266. <div class="editor-sign-box">
  267. <input class="editor-sign-box" type="text" name="" id="editor-input-tags"
  268. placeholder="多个标签请用英文逗号分割,如:标签A,标签B,标签C"
  269. autocomplete="off" style="border: none; text-indent: 10px">
  270. </div>
  271. <div style="clear: both"></div>
  272. </div>
  273. <div style="clear: both"></div>
  274. <div class="editor-footer">
  275. <div class="layui-inline"> <label class="layui-form-label">设置计划推文时间</label>
  276. <div class="layui-input-inline" style="margin-right: 40px">
  277. <input type="text" class="layui-input" id="plan-push-time" placeholder="默认立刻推送">
  278. </div>
  279. </div>
  280. <button id="editor-publish-btn" style="background-color: #00c166; color: white">立即推文</button>
  281. </div>
  282. </div>
  283. </center>
  284. <script src="/js/common/login.js"></script>
  285. <script>
  286. var me;
  287. loadCurrUserInfo();
  288. function loadCurrUserInfo() {
  289. $.ajax({
  290. url:"/api/user/getCurrentUserInfo",
  291. type:"get",
  292. success:function (data) {
  293. data = eval(data);
  294. if (data.success){
  295. data = data.data;
  296. me = data;
  297. $("#author-photo").attr("src", me.photo);
  298. } else {
  299. location.href="/h5/auth";
  300. }
  301. },error:function () {
  302. location.href="/h5/auth";
  303. }
  304. })
  305. }
  306. // 获取URL请求参数
  307. function getUserParamByName(key) {
  308. var url = window.location.search;
  309. var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
  310. var result = url.substr(1).match(reg);
  311. return result ? decodeURIComponent(result[2]) : "";
  312. }
  313. // 计划推文时间
  314. var planPushTime = '';
  315. var articleId = getUserParamByName("id");
  316. /**
  317. * 富文本编辑器 wangEditor 配置
  318. */
  319. const { createEditor, createToolbar } = window.wangEditor
  320. const editorConfig = {
  321. placeholder: '文章正文...',
  322. MENU_CONF: {}
  323. }
  324. editorConfig.MENU_CONF['uploadImage'] = {
  325. server: '/api/file/updateForEditor',
  326. timeout: 5 * 1000, // 5s
  327. fieldName: 'file',
  328. uploadImgMaxLength: 1,
  329. maxFileSize: 5 * 1024 * 1024, // 10M
  330. uploadImgAccept: ['jpg', 'jpeg', 'png'],
  331. onFailed(file, res) {
  332. layer.msg("图片上传失败");
  333. },
  334. onError(file, err, res) {
  335. layer.msg("图片上传失败");
  336. }
  337. }
  338. editorConfig.MENU_CONF['uploadVideo'] = {
  339. server: '/api/file/uploadForWangEditor',
  340. // form-data fieldName ,默认值 'wangeditor-uploaded-video'
  341. fieldName: 'file',
  342. // 单个文件的最大体积限制,默认为 20M
  343. maxFileSize: 20 * 1024 * 1024, // 2M
  344. // 最多可上传几个文件,默认为 5
  345. maxNumberOfFiles: 1,
  346. // 选择文件时的类型限制,默认为 ['video/*'] 。如不想限制,则设置为 []
  347. allowedFileTypes: ['video/*'],
  348. // 超时时间,默认为 30 秒
  349. timeout: 15 * 1000, // 15 秒
  350. }
  351. const editor = createEditor({
  352. selector: '#content',
  353. html: '<p><br></p>',
  354. config: editorConfig,
  355. mode: 'default', // or 'simple'
  356. })
  357. const toolbarConfig = {}
  358. toolbarConfig.excludeKeys = [
  359. 'group-indent',
  360. 'todo',
  361. 'undo',
  362. 'redo'
  363. ]
  364. const toolbar = createToolbar({
  365. editor,
  366. selector: '#toolbar-container',
  367. config: toolbarConfig,
  368. mode: 'default', // 'default' or 'simple'
  369. })
  370. layui.use(['upload'], function(){
  371. var $ = layui.jquery
  372. ,upload = layui.upload
  373. //常规使用 - 普通图片上传
  374. upload.render({
  375. elem: '#editor-cover-image-upload'
  376. ,url: '/api/file/moment/upload' //改成您自己的上传接口
  377. ,accept: 'images'
  378. ,acceptMime: '*'
  379. ,done: function(res){
  380. if(!res.success){
  381. return layer.msg('上传失败');
  382. $("#editor-cover-image-upload-default").show();
  383. $("#editor-cover-image").hide();
  384. } else {
  385. $('#editor-cover-image').attr('src', res.data.url);
  386. $("#editor-cover-image").show();
  387. $("#editor-cover-image-upload-default").hide();
  388. }
  389. }
  390. });
  391. });
  392. loadPublicAccounts();
  393. function loadPublicAccounts() {
  394. $.ajax({
  395. url:"/api/public-account/list",
  396. type:"get",
  397. success:function (data) {
  398. data = eval(data);
  399. if (data.success){
  400. var accountList = data.data;
  401. $("#public-account-select").append("<option value=''>--- 选择公众号 ---</option>");
  402. $.each(accountList, function (index, publicAccount) {
  403. $("#public-account-select").append("<option value='"+publicAccount.id+"'>"+publicAccount.name+"</option>");
  404. })
  405. }
  406. }
  407. })
  408. }
  409. $("#editor-publish-btn").on('click', function () {
  410. var publicAccount = $("#public-account-select").val();
  411. var title = $("#editor-title").val();
  412. var description = $("#editor-description-input").val();
  413. var cover = $("#editor-cover-image").attr("src");
  414. var signs = $("#editor-input-tags").val();
  415. var content = $("#content").html();
  416. if (publicAccount == '') {
  417. layer.msg("请先选择公众号");
  418. return;
  419. }
  420. if (title == '' || title.length > 100 || title.length < 5) {
  421. layer.msg("标题5~100字");
  422. return;
  423. }
  424. if (signs == '') {
  425. layer.msg("标签不能为空");
  426. return;
  427. }
  428. if (description == '' || description.length > 300) {
  429. layer.msg("文章描述为空或不合法");
  430. return;
  431. }
  432. if (cover == '') {
  433. layer.msg("封面图不能为空");
  434. return;
  435. }
  436. if (title != '') {
  437. title = title;
  438. }
  439. if (description != '') {
  440. description = description;
  441. }
  442. $.ajax({
  443. url: "/api/article/save",
  444. type: "post",
  445. dataType: "json",
  446. contentType: "application/json;charset=utf-8",
  447. data: JSON.stringify({
  448. id: articleId,
  449. publicAccount: publicAccount,
  450. title: title,
  451. signs: signs,
  452. description: description,
  453. cover: cover,
  454. content: content,
  455. planPushTime: planPushTime
  456. }),
  457. success: function (data) {
  458. data = eval(data);
  459. if (data.success){
  460. articleId = data.data;
  461. layer.msg("文章已提交");
  462. window.open("/article/"+articleId);
  463. } else {
  464. layer.msg(data.msg);
  465. }
  466. },error:function () {
  467. layer.msg("服务端异常");
  468. }
  469. })
  470. })
  471. </script>
  472. <script>
  473. layui.use('laydate', function(){
  474. var laydate = layui.laydate;
  475. //日期时间选择器
  476. laydate.render({
  477. elem: '#plan-push-time'
  478. ,type: 'datetime'
  479. ,done: function(value, date, endDate){
  480. // 将日期转换为时间戳
  481. planPushTime = new Date(value).getTime();
  482. if (isNaN(planPushTime)) {
  483. $("#editor-publish-btn").text("立即推文");
  484. } else {
  485. $("#editor-publish-btn").text("定时推文");
  486. }
  487. }
  488. });
  489. });
  490. </script>
  491. </body>
  492. </html>