info.blade.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. @extends('admin.layouts')
  2. @section('css')
  3. <link href="/assets/global/vendor/dropify/dropify.min.css" rel="stylesheet">
  4. <link href="/assets/global/vendor/bootstrap-select/bootstrap-select.min.css" rel="stylesheet">
  5. @endsection
  6. @section('content')
  7. <div class="page-content container">
  8. <div class="panel">
  9. <div class="panel-heading">
  10. <h2 class="panel-title">
  11. {{ isset($article) ? trans('admin.action.edit_item', ['attribute' => trans('model.article.attribute')]) : trans('admin.action.add_item', ['attribute' => trans('model.article.attribute')]) }}
  12. </h2>
  13. </div>
  14. @if ($errors->any())
  15. <x-alert type="danger" :message="$errors->all()" />
  16. @endif
  17. @if (Session::has('successMsg'))
  18. <x-alert type="success" :message="Session::pull('successMsg')" />
  19. @endif
  20. <div class="panel-body">
  21. <form class="form-horizontal" action="{{ isset($article) ? route('admin.article.update', $article) : route('admin.article.store') }}"
  22. enctype="multipart/form-data" method="post">@csrf
  23. @isset($article)
  24. @method('PUT')
  25. @endisset
  26. <div class="form-group row">
  27. <label class="col-form-label col-md-2" for="type"> {{ trans('model.common.type') }} </label>
  28. <div class="col-md-10 d-flex align-items-center">
  29. <div class="radio-custom radio-primary radio-inline">
  30. <input name="type" type="radio" value="1" checked />
  31. <label for="type">{{ trans('admin.article.type.knowledge') }}</label>
  32. </div>
  33. <div class="radio-custom radio-primary radio-inline">
  34. <input name="type" type="radio" value="2" />
  35. <label for="type">{{ trans('admin.article.type.announcement') }}</label>
  36. </div>
  37. </div>
  38. </div>
  39. <div class="form-group row">
  40. <label class="col-form-label col-md-2" for="title"> {{ trans('validation.attributes.title') }} </label>
  41. <div class="col-md-4">
  42. <input class="form-control" id="title" name="title" type="text" autofocus required />
  43. </div>
  44. </div>
  45. <div class="form-group row article">
  46. <label class="col-form-label col-md-2" for="category"> {{ trans('model.article.category') }} </label>
  47. <div class="col-md-4">
  48. @if (isset($categories))
  49. <input class="form-control" id="category" name="category" type="text" list="category_list" />
  50. <datalist id="category_list">
  51. @foreach ($categories as $category)
  52. <option value="{{ $category->category }}">{{ $category->category }}</option>
  53. @endforeach
  54. </datalist>
  55. @else
  56. <input class="form-control" id="category" name="category" type="text" />
  57. @endif
  58. <span class="text-help"> {{ trans('admin.article.category_hint') }} </span>
  59. </div>
  60. </div>
  61. <div class="form-group row">
  62. <label class="col-form-label col-md-2" for="language"> {{ trans('model.article.language') }} </label>
  63. <div class="col-md-4">
  64. <select class="form-control" id="language" name="language" data-plugin="selectpicker" data-style="btn-outline btn-primary">
  65. @foreach (config('common.language') as $key => $value)
  66. <option value="{{ $key }}">
  67. <i class="fi fi-{{ $value[1] }}" aria-hidden="true"></i>
  68. <span style="padding: inherit;">{{ $value[0] }}</span>
  69. </option>
  70. @endforeach
  71. </select>
  72. </div>
  73. </div>
  74. <div class="form-group row article">
  75. <label class="col-form-label col-md-2" for="sort"> {{ trans('model.common.sort') }} </label>
  76. <div class="col-md-2">
  77. <input class="form-control" id="sort" name="sort" type="number" value="10" min="0" max="255" required />
  78. <span class="text-help"> {{ trans('admin.sort_asc') }} </span>
  79. </div>
  80. </div>
  81. <div class="form-group row">
  82. <label class="col-form-label col-md-2" for="logo"> {{ trans('model.article.logo') }} </label>
  83. <div class="col-md-4">
  84. <input id="logo" name="logo" data-plugin="dropify"
  85. data-default-file="{{ asset($article->logo ?? '/assets/images/default.png') }}" type="file" />
  86. <input class="form-control" id="logoUrl" type="text" placeholder="{{ trans('admin.article.logo_placeholder') }}">
  87. </div>
  88. </div>
  89. <div class="form-group row">
  90. <label class="col-form-label col-md-2" for="content"> {{ trans('validation.attributes.content') }} </label>
  91. <div class="col-md-10">
  92. <textarea class="form-control" name="content">
  93. @isset($article)
  94. {!! $article->content !!}
  95. @endisset
  96. </textarea>
  97. </div>
  98. </div>
  99. <div class="form-actions text-right">
  100. <div class="btn-group">
  101. <a class="btn btn-danger" href="{{ route('admin.article.index') }}">{{ trans('common.back') }}</a>
  102. <button class="btn btn-success" type="submit">{{ trans('common.submit') }}</button>
  103. </div>
  104. </div>
  105. </form>
  106. </div>
  107. </div>
  108. </div>
  109. @endsection
  110. @section('javascript')
  111. <script src="/assets/global/vendor/dropify/dropify.min.js"></script>
  112. <script src="/assets/global/js/Plugin/dropify.js"></script>
  113. <script src="/assets/custom/tinymce/tinymce.min.js"></script>
  114. <script src="/assets/global/vendor/bootstrap-select/bootstrap-select.min.js"></script>
  115. <script src="/assets/global/js/Plugin/bootstrap-select.js"></script>
  116. <script>
  117. $(document).ready(function() {
  118. const $type = $('input:radio[name="type"]')
  119. const $logo = $('#logo')
  120. const $logoUrl = $('#logoUrl')
  121. let logoCleared = false
  122. // 初始化 TinyMCE
  123. tinymce.init({
  124. selector: 'textarea', // change this value according to your HTML
  125. license_key: 'gpl',
  126. plugins: 'advlist autolink autoresize autosave code emoticons help image importcss link lists media ' +
  127. 'preview quickbars searchreplace table visualblocks visualchars wordcount',
  128. toolbar: 'restoredraft undo redo | styles | bold italic forecolor backcolor emoticons| alignleft aligncenter alignright alignjustify' +
  129. ' | bullist numlist outdent indent | link image media',
  130. menubar: 'view edit insert format table tools help',
  131. link_default_target: '_blank',
  132. quickbars_insert_toolbar: 'quicktable image media',
  133. quickbars_selection_toolbar: 'bold italic underline | blocks | bullist numlist | blockquote quicklink',
  134. extended_valid_elements: 'button[onclick|class],i[class|aria-hidden]', // Allow more attributes for <a>
  135. language: '{{ app()->getLocale() }}',
  136. content_css: [
  137. '/assets/bundle/app.min.css',
  138. '/assets/global/fonts/font-awesome/css/all.min.css',
  139. '/assets/global/fonts/material-design/material-design.min.css',
  140. '/assets/global/fonts/web-icons/web-icons.min.css',
  141. 'https://fonts.loli.net/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap',
  142. '/assets/custom/articles.min.css',
  143. '/assets/custom/tinymce.min.css'
  144. ],
  145. min_height: 500,
  146. max_height: 800,
  147. })
  148. // 初始化已有文章数据
  149. @isset($article)
  150. $type.filter(`[value="${@json($article->type)}"]`).click()
  151. $('#title').val(@json($article->title))
  152. $('#category').val(@json($article->category))
  153. $('#language').selectpicker('val', @json($article->language))
  154. $('#sort').val(@json($article->sort))
  155. @endisset
  156. // 初始化 Dropify
  157. const dropify = $logo.dropify().data('dropify')
  158. // 类型切换处理
  159. $type.on('change', function() {
  160. $('.article').toggle($(this).val() === '1')
  161. })
  162. // 添加 Dropify clear 事件处理
  163. $logo.on('dropify.afterClear', function() {
  164. logoCleared = true
  165. })
  166. // Logo URL 输入处理
  167. $logoUrl.on('input', handleLogoUrlInput)
  168. // 表单提交处理
  169. $('form').on('submit', handleFormSubmit)
  170. function handleLogoUrlInput() {
  171. const imageUrl = $logoUrl.val()
  172. if (imageUrl) {
  173. updateDropifyPreview(imageUrl)
  174. } else {
  175. dropify.resetPreview()
  176. dropify.clearElement()
  177. }
  178. }
  179. function updateDropifyPreview(imageUrl) {
  180. dropify.settings.defaultFile = imageUrl
  181. dropify.destroy()
  182. $logo.dropify({
  183. defaultFile: imageUrl
  184. }).data('dropify').init()
  185. }
  186. function handleFormSubmit(event) {
  187. const logoUrl = $logoUrl.val()
  188. if (logoUrl || (logoCleared && !$logo.val())) {
  189. $logo.attr('type', 'text').val(logoUrl || null)
  190. }
  191. }
  192. })
  193. </script>
  194. @endsection