Calendar.cshtml 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. @using VberAdmin.Web.Models.Input
  2. @using VberAdmin.Web.Models.Modals
  3. @{
  4. ViewBag.ActiveMenu = PermissionNames.Vber;
  5. ViewBag.Title = L("MyCalendar");
  6. string notifyType = ViewBag.NotifyType;
  7. var m_body = new VmModalBody().AddInputs(new List<VmInputBase>()
  8. {
  9. new VmInputHidden("id"),
  10. new VmInput("title", "日程名称").WithRequired(),
  11. new VmInputTextarea("description", "日程详情").WithRequired(),
  12. new VmInputCheckBox("allDay","").AddItems(new VmInputCheckBoxRadioItem("全天日程","true").WithOther("data-vb-calendar-input=\"allDay\"")),
  13. }).AddGroup(new List<VmInputBase>()
  14. {
  15. new VmInputDate("start","开始日期").WithRequired(),
  16. new VmInputDate("end","结束日期").WithRequired(),
  17. }).AddGroup(new List<VmInputBase>()
  18. {
  19. new VmInputDateTime("startTime","").WithOnlyTime().WithOther("data-vb-calendar-input=\"time\""),
  20. new VmInputDateTime("endTime","").WithOnlyTime().WithOther("data-vb-calendar-input=\"time\""),
  21. }).AddInputs(new List<VmInputBase>()
  22. {
  23. new VmInput("notifyType","通知方式").WithSelect(notifyType,isMultiple:true),
  24. new VmInputRadio("style", "日程样式").AddItems(
  25. new VmInputCheckBoxRadioItem("<div class=\"bg-primary text-inverse-primary px-3 py-1\">样式1</div>", "1").WithClass("text-primary"),
  26. new VmInputCheckBoxRadioItem("<div class=\"bg-success text-inverse-success px-3 py-1\">样式2</div>", "2").WithClass("text-success"),
  27. new VmInputCheckBoxRadioItem("<div class=\"bg-info text-inverse-info px-3 py-1\">样式3</div>", "3").WithClass("text-info"),
  28. new VmInputCheckBoxRadioItem("<div class=\"bg-danger text-inverse-danger px-3 py-1\">样式4</div>", "4").WithClass("text-danger"),
  29. new VmInputCheckBoxRadioItem("<div class=\"bg-warning text-inverse-warning px-3 py-1\">样式5</div>", "5").WithClass("text-warning"),
  30. new VmInputCheckBoxRadioItem("<div class=\"bg-dark text-inverse-dark px-3 py-1\">样式6</div>", "6").WithClass("text-dark")
  31. ).WithRequired(),
  32. });
  33. var modal = new VmModal().WithOther("data-vb-calendar-modal").WithHeaderAndFooter("日程","").WithBody( m_body);
  34. }
  35. @section css{
  36. <link href="/Metronic/assets/plugins/custom/fullcalendar/fullcalendar.bundle.css" rel="stylesheet" />
  37. }
  38. @section styles
  39. {
  40. <style>
  41. .fc .fc-list-empty-cushion {
  42. color: #dc3545 !important;
  43. font-size: 1.75rem;
  44. }
  45. </style>
  46. }
  47. <div class="container">
  48. <div class="card">
  49. <div class="card-header">
  50. <h2 class="card-title fw-bolder">我的日程</h2>
  51. <div class="card-toolbar">
  52. <a href="#" type="button" class="btn btn-flex btn-primary" data-vb-calendar-btn="add">
  53. <!--Svg Icon | path: icons/duotone/Navigation/Plus.svg-->
  54. <span class="svg-icon svg-icon-2">
  55. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1">
  56. <rect fill="#000000" x="4" y="11" width="16" height="2" rx="1" />
  57. <rect fill="#000000" opacity="0.5" transform="translate(12.000000, 12.000000) rotate(-270.000000) translate(-12.000000, -12.000000)" x="4" y="11" width="16" height="2" rx="1" />
  58. </svg>
  59. </span>添加日程</a>
  60. </div>
  61. </div>
  62. <div class="card-body">
  63. <div data-vb-calebdar=""></div>
  64. </div>
  65. </div>
  66. </div>
  67. @await Html.PartialAsync("_Modal", modal)
  68. @section scripts
  69. {
  70. <script src="/Metronic/assets/plugins/custom/fullcalendar/fullcalendar.bundle.js" asp-append-version="false"></script>
  71. <script>
  72. var VbCalendar = function() {
  73. const
  74. DATA = "calendar",
  75. EVENT_KEY = `.${DATA}`,
  76. BTN = 'vb-calendar-btn',
  77. ClassName = {
  78. CALENDAR_BODY: `vb-calebdar`,
  79. BTN_MORE_VIEW: `more-view-btn_${DATA}`,
  80. BTN_ADD: `${BTN}="add"`,
  81. BTN_EDIT: `${BTN}="edit"`,
  82. BTN_DELETE: `${BTN}="delete"`,
  83. BTN_SUBMIT: `${BTN}="submit"`,
  84. BTN_CANCEL: `${BTN}="cancel"`,
  85. BTN_CLOSE: `${BTN}="close"`,
  86. MODAL: `vb-calendar-modal`,
  87. MODAL_VIEW: `modal_view`,
  88. TITLE: `title`,
  89. DESCRIPTION: `description`,
  90. ALL_DAY: 'allDay',
  91. START_DATE: 'startDate',
  92. START_TIME: 'startTime',
  93. END_DATE: 'endDate',
  94. END_TIME: 'endTime',
  95. STYLE: 'style',
  96. DETAIL: "vb-calendar-detail"
  97. },
  98. Selector = {
  99. CALENDAR_BODY: `[data-${ClassName.CALENDAR_BODY}]`,
  100. BTN_MORE_VIEW: `#${ClassName.BTN_MORE_VIEW}`,
  101. BTN_ADD: `[data-${ClassName.BTN_ADD}]`,
  102. BTN_EDIT: `[data-${ClassName.BTN_EDIT}]`,
  103. BTN_DELETE: `[data-${ClassName.BTN_DELETE}]`,
  104. MODAL: `[data-${ClassName.MODAL}="modal"]`,
  105. MODAL_VIEW: `#${ClassName.MODAL_VIEW}`,
  106. FORM_TITLE: `[name="${ClassName.TITLE}"]`,
  107. FORM_DESCRIPTION: `[name="${ClassName.DESCRIPTION}"]`,
  108. FORM_ALL_DAY: `[name="${ClassName.ALL_DAY}"]`,
  109. FORM_START_DATE: `[name="${ClassName.START_DATE}"]`,
  110. FORM_START_TIME: `[name="${ClassName.START_TIME}"]`,
  111. FORM_END_DATE: `[name="${ClassName.END_DATE}"]`,
  112. FORM_END_TIME: `[name="${ClassName.END_TIME}"]`,
  113. FORM_STYLE: `[name="${ClassName.STYLE}"]`,
  114. DETAIL_TITLE: `[data-${ClassName.DETAIL}="${ClassName.TITLE}"]`,
  115. DETAIL_DESCRIPTION: `[data-${ClassName.DETAIL}="${ClassName.DESCRIPTION}"]`,
  116. DETAIL_ALL_DAY: `[data-${ClassName.DETAIL}="${ClassName.ALL_DAY}"]`,
  117. DETAIL_START_DATE: `[data-${ClassName.DETAIL}="${ClassName.START_DATE}"]`,
  118. DETAIL_END_DATE: `[data-${ClassName.DETAIL}="${ClassName.END_DATE}"]`,
  119. TIME: `[data-vb-calendar-input="time"]`
  120. };
  121. let $fullCalendar,
  122. fullCalendar,
  123. _triggerChangeEvent = true,
  124. popoverIsInit = false,
  125. popover,
  126. $modal,
  127. $form,
  128. today,
  129. calendarData = {
  130. id: "",
  131. eventName: "",
  132. eventDescription: "",
  133. startDate: "",
  134. endDate: "",
  135. allDay: false,
  136. notifyType: "",
  137. style: "",
  138. backgroundColor: "",
  139. borderColor: "",
  140. textColor: ""
  141. };
  142. const
  143. popoverDestroy = function() {
  144. popoverIsInit && (popover.dispose(), popoverIsInit = false);
  145. },
  146. loadEvent= (info, successCallback) => {
  147. console.log("Calendar Events Load From: 【" + info.startStr + "】 To 【" + info.endStr + "】");
  148. $.vbAjax4({
  149. url: abp.appUrl + "calendar/getAll",
  150. data: {
  151. SearchList: [
  152. {
  153. "KeyField": "start",
  154. "KeyWords": info.start
  155. },
  156. {
  157. "KeyField": "end",
  158. "KeyWords": info.end
  159. }
  160. ]
  161. },
  162. success: function(res) {
  163. successCallback(res);
  164. }
  165. });
  166. },
  167. submit = (type) => {
  168. let data = $form.formSerialize();
  169. var $checkedStyle = $form.find(Selector.FORM_STYLE + ':checked').next().find('div').eq(0);
  170. data.colors = $checkedStyle.css('color') +
  171. "|" +
  172. $checkedStyle.css('background-color') +
  173. "|" +
  174. $checkedStyle.css('background-color');
  175. data.start = data.start + (data.startTime ? " " + data.startTime : "");
  176. data.end = data.end + (data.endTime ? " " + data.endTime : "");
  177. if (new Date(data.end) <= new Date(data.start)) {
  178. abp.message.warn("开始日期不能小于结束日期");
  179. return;
  180. }
  181. $.vbAjax({
  182. url: abp.appUrl + `Calendar/${type == "add" ? "Create" : "Update"}`,
  183. data: data,
  184. success: (res) => {
  185. $modal.VbModal('hide');
  186. if (type == "add") {
  187. let newEvent = {
  188. id: res.id,
  189. title: res.title,
  190. description: res.description,
  191. backgroundColor: res.backgroundColor,
  192. borderColor: res.borderColor,
  193. textColor: res.textColor,
  194. colors: res.colors,
  195. notifyType: res.notifyType,
  196. allDay: res.allDay,
  197. start: moment(res.start).format(),
  198. end: moment(res.end).format()
  199. }
  200. fullCalendar.addEvent(newEvent);
  201. } else {
  202. var event = fullCalendar.getEventById(res.id);
  203. _triggerChangeEvent = false;
  204. event.setStart(res.start);
  205. event.setEnd(res.end);
  206. event.setAllDay(res.allDay);
  207. event.setProp("title", res.title);
  208. event.setProp("backgroundColor", res.backgroundColor);
  209. event.setProp("borderColor", res.borderColor);
  210. event.setProp("textColor", res.textColor);
  211. event.setExtendedProp("description", res.description);
  212. event.setExtendedProp("notifyType", res.notifyType);
  213. event.setExtendedProp("colors", res.colors);
  214. _triggerChangeEvent = true;
  215. }
  216. },
  217. error:() => {
  218. fullCalendar.refetchEvents();
  219. }
  220. });
  221. },
  222. add = () => {
  223. $modal.VbModal({
  224. opTitle: "添加",
  225. data: {
  226. start: calendarData.startDate,
  227. end: calendarData.endDate,
  228. notifyType: 1,
  229. style: 1,
  230. allDay: "true"
  231. },
  232. showAfter: () => {
  233. $(Selector.TIME).closest('.flex-column').addClass('d-none');
  234. },
  235. save: () => { submit("add"); }
  236. });
  237. },
  238. update = () => {
  239. $(Selector.MODAL_VIEW).VbModal('hide');
  240. $modal.VbModal({
  241. opTitle: "修改",
  242. data: {
  243. id: calendarData.id,
  244. title: calendarData.eventName,
  245. description: calendarData.eventDescription,
  246. start: moment(calendarData.startDate).format("YYYY-MM-DD HH:mm"),
  247. startTime: moment(calendarData.startDate).format("HH:mm"),
  248. end: moment(calendarData.endDate).format("YYYY-MM-DD HH:mm"),
  249. endTime: moment(calendarData.endDate).format("HH:mm"),
  250. notifyType: calendarData.notifyType,
  251. style: calendarData.style,
  252. allDay: calendarData.allDay + ""
  253. },
  254. showAfter: () => {
  255. calendarData.allDay ? $(Selector.TIME).closest('.flex-column').addClass('d-none') : $(Selector.TIME).closest('.flex-column').removeClass('d-none');
  256. },
  257. save: () => { submit("update"); }
  258. });
  259. },
  260. change = (event, successCallBack, errCallback) =>{
  261. let data = {
  262. id: event.id,
  263. title: event.title,
  264. start: event.startStr || event.start,
  265. end: event.endStr || event.end,
  266. allDay: event.allDay,
  267. description: event.description || event.extendedProps.description,
  268. notifyType: (event.notifyType || event.extendedProps.notifyType).join(","),
  269. colors: event.colors || event.extendedProps.colors
  270. };
  271. $.vbAjax4({
  272. url: abp.appUrl + "Calendar/Update",
  273. data: data,
  274. success: function (res) {
  275. if (successCallBack) {
  276. successCallBack.call(res);
  277. }
  278. },
  279. error: function (error) {
  280. console.log(error);
  281. abp.message.error(error.message).done(function () {
  282. fullCalendar.getEventById(event.id).remove();
  283. if (errCallback) {
  284. errCallback.call();
  285. }
  286. });
  287. }
  288. });
  289. },
  290. delete_ = () => {
  291. MsgConfirm("确认删除 [" + calendarData.eventName + "] 日程事件吗?", "确认删除", () =>{
  292. $.vbAjax1({
  293. url: abp.appUrl + "Calendar/Delete?id=" + calendarData.id,
  294. success: () =>{
  295. fullCalendar.getEventById(calendarData.id).remove();
  296. $(Selector.MODAL_VIEW).VbModal('hide');
  297. }
  298. });
  299. });
  300. },
  301. createViewModal = () => {
  302. let allDayStr, startStr, endStr;
  303. calendarData.allDay
  304. ? (allDayStr = "全天", startStr = moment(calendarData.startDate).format("YYYY-MM-DD"), endStr = !calendarData.endDate ? "" : moment(calendarData.endDate).format("YYYY-MM-DD"))
  305. : (allDayStr = "", startStr = moment(calendarData.startDate).format("YYYY-MM-DD HH:mm"),
  306. endStr = moment(calendarData.endDate).format("YYYY-MM-DD HH:mm"));
  307. $(document).VbModal('create',
  308. {
  309. modalId: ClassName.MODAL_VIEW,
  310. title: "",
  311. dialogClass: "mw-650px",
  312. modalHeader: `<div class="modal-header pt-5 pb-0 border-0 justify-content-end">
  313. <div class="btn btn-icon btn-sm btn-color-gray-400 btn-active-icon-primary me-2" data-bs-toggle="tooltip" data-bs-dismiss="click" title="修改日程" data-${ClassName.BTN_EDIT}>
  314. <!--Svg Icon | path: icons/duotone/General/Edit.svg-->
  315. <span class="svg-icon svg-icon-2">
  316. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1">
  317. <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
  318. <rect x="0" y="0" width="24" height="24" />
  319. <path d="M7.10343995,21.9419885 L6.71653855,8.03551821 C6.70507204,7.62337518 6.86375628,7.22468355 7.15529818,6.93314165 L10.2341093,3.85433055 C10.8198957,3.26854411 11.7696432,3.26854411 12.3554296,3.85433055 L15.4614112,6.9603121 C15.7369117,7.23581259 15.8944065,7.6076995 15.9005637,7.99726737 L16.1199293,21.8765672 C16.1330212,22.7048909 15.4721452,23.3869929 14.6438216,23.4000848 C14.6359205,23.4002097 14.6280187,23.4002721 14.6201167,23.4002721 L8.60285976,23.4002721 C7.79067946,23.4002721 7.12602744,22.7538546 7.10343995,21.9419885 Z" fill="#000000" fill-rule="nonzero" transform="translate(11.418039, 13.407631) rotate(-135.000000) translate(-11.418039, -13.407631)" />
  320. </g>
  321. </svg>
  322. </span>
  323. </div>
  324. <div class="btn btn-icon btn-sm btn-color-gray-400 btn-active-icon-danger me-2" data-bs-toggle="tooltip" data-bs-dismiss="click" title="删除日程" data-${ClassName.BTN_DELETE}>
  325. <!--Svg Icon | path: icons/duotone/General/Trash.svg-->
  326. <span class="svg-icon svg-icon-2">
  327. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1">
  328. <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
  329. <rect x="0" y="0" width="24" height="24" />
  330. <path d="M6,8 L6,20.5 C6,21.3284271 6.67157288,22 7.5,22 L16.5,22 C17.3284271,22 18,21.3284271 18,20.5 L18,8 L6,8 Z" fill="#000000" fill-rule="nonzero" />
  331. <path d="M14,4.5 L14,4 C14,3.44771525 13.5522847,3 13,3 L11,3 C10.4477153,3 10,3.44771525 10,4 L10,4.5 L5.5,4.5 C5.22385763,4.5 5,4.72385763 5,5 L5,5.5 C5,5.77614237 5.22385763,6 5.5,6 L18.5,6 C18.7761424,6 19,5.77614237 19,5.5 L19,5 C19,4.72385763 18.7761424,4.5 18.5,4.5 L14,4.5 Z" fill="#000000" opacity="0.3" />
  332. </g>
  333. </svg>
  334. </span>
  335. </div>
  336. <div class="btn btn-icon btn-sm btn-color-gray-500 btn-active-icon-primary" data-bs-toggle="tooltip" title="关闭详情" data-bs-dismiss="modal">
  337. <!--Svg Icon | path: icons/duotone/Navigation/Close.svg-->
  338. <span class="svg-icon svg-icon-1">
  339. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1">
  340. <g transform="translate(12.000000, 12.000000) rotate(-45.000000) translate(-12.000000, -12.000000) translate(4.000000, 4.000000)" fill="#000000">
  341. <rect fill="#000000" x="0" y="7" width="16" height="2" rx="1" />
  342. <rect fill="#000000" opacity="0.5" transform="translate(8.000000, 8.000000) rotate(-270.000000) translate(-8.000000, -8.000000)" x="0" y="7" width="16" height="2" rx="1" />
  343. </g>
  344. </svg>
  345. </span>
  346. </div>
  347. </div>`,
  348. modalBody: `<form>
  349. <div class="d-flex">
  350. <!--Svg Icon | path: icons/duotone/Interface/Calendar.svg-->
  351. <span class="svg-icon svg-icon-1 svg-icon-muted me-5">
  352. <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
  353. <path opacity="0.25" fill-rule="evenodd" clip-rule="evenodd" d="M6 3C6 2.44772 6.44772 2 7 2C7.55228 2 8 2.44772 8 3V4H16V3C16 2.44772 16.4477 2 17 2C17.5523 2 18 2.44772 18 3V4H19C20.6569 4 22 5.34315 22 7V19C22 20.6569 20.6569 22 19 22H5C3.34315 22 2 20.6569 2 19V7C2 5.34315 3.34315 4 5 4H6V3Z" fill="#191213" />
  354. <path fill-rule="evenodd" clip-rule="evenodd" d="M10 12C9.44772 12 9 12.4477 9 13C9 13.5523 9.44772 14 10 14H17C17.5523 14 18 13.5523 18 13C18 12.4477 17.5523 12 17 12H10ZM7 16C6.44772 16 6 16.4477 6 17C6 17.5523 6.44772 18 7 18H13C13.5523 18 14 17.5523 14 17C14 16.4477 13.5523 16 13 16H7Z" fill="#121319" />
  355. </svg>
  356. </span>
  357. <div class="mb-5">
  358. <div class="d-flex align-items-center mb-2">
  359. <span class="fs-3 fw-bolder me-3" data-vb-calendar-detail="title">${calendarData.eventName}</span>
  360. <span class="badge badge-light-success" data-vb-calendar-detail="allDay">${allDayStr}</span>
  361. </div>
  362. <div class="fs-6" data-vb-calendar-detail="description">${calendarData.eventDescription ? calendarData.eventDescription : "--"}</div>
  363. </div>
  364. </div>
  365. <div class="d-flex align-items-center mb-2">
  366. <!--Svg Icon | path: icons/duotone/Design/Circle.svg-->
  367. <span class="svg-icon svg-icon-1 svg-icon-success me-5">
  368. <svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" version="1.1">
  369. <circle fill="#000000" cx="12" cy="12" r="8" />
  370. </svg>
  371. </span>
  372. <div class="fs-6">
  373. <span class="fw-bolder">开始日期:</span>
  374. <span data-vb-calendar-detail="startDate">${startStr}</span>
  375. </div>
  376. </div>
  377. <div class="d-flex align-items-center mb-3">
  378. <!--begin::Icon-->
  379. <span class="svg-icon svg-icon-1 svg-icon-danger me-5">
  380. <svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" version="1.1">
  381. <circle fill="#000000" cx="12" cy="12" r="8" />
  382. </svg>
  383. </span>
  384. <div class="fs-6">
  385. <span class="fw-bolder">结束日期:</span>
  386. <span data-vb-calendar-detail="endDate">${endStr}</span>
  387. </div>
  388. </div>
  389. </form>`,
  390. modalFooter: '',
  391. shown: (e) => {
  392. //console.log(e);
  393. //let $modal_view = $('#modal_view');
  394. $(e).find(Selector.BTN_EDIT).on(`click${EVENT_KEY}`,
  395. () => {
  396. update();
  397. });
  398. $(e).find(Selector.BTN_DELETE).on(`click${EVENT_KEY}`,
  399. () => {
  400. delete_();
  401. });
  402. }
  403. });
  404. },
  405. convertData = (e) => {
  406. calendarData.id = e.id;
  407. calendarData.eventName = e.title;
  408. calendarData.eventDescription = e.description;
  409. calendarData.notifyType = e.notifyType;
  410. calendarData.style = 1;
  411. calendarData.backgroundColor = e.backgroundColor;
  412. calendarData.borderColor = e.borderColor;
  413. calendarData.textColor = e.textColor;
  414. calendarData.startDate = e.startStr;
  415. calendarData.endDate = e.endStr;
  416. calendarData.allDay = e.allDay;
  417. if (calendarData.backgroundColor) {
  418. let backgroundColor = calendarData.backgroundColor.indexOf('#') == 0
  419. ? HexToRgbStr(calendarData.backgroundColor)
  420. : calendarData.backgroundColor;
  421. $form.find(Selector.FORM_STYLE).next('span').find('div').each(function () {
  422. if ($(this).css('background-color') === backgroundColor) {
  423. calendarData.style = $(this).parent().prev().val();
  424. }
  425. });
  426. }
  427. },
  428. popoverShow = (e) => {
  429. popoverDestroy();
  430. const startD = calendarData.allDay ? moment(calendarData.startDate).format("YYYY-MM-DD") : moment(calendarData.startDate).format("YYYY-MM-DD HH:mm"),
  431. endD = !calendarData.endDate ? "" : calendarData.allDay ? moment(calendarData.endDate).format("YYYY-MM-DD") : moment(calendarData.endDate).format("YYYY-MM-DD HH:mm");
  432. var opt = {
  433. container: "body",
  434. trigger: "manual",
  435. boundary: "window",
  436. placement: "auto",
  437. dismiss: true,
  438. html: true,
  439. title: "日程概览",
  440. content: `<div class="fw-bolder mb-2">${calendarData.eventName}</div>
  441. <div class="fs-7"><span class="fw-bold">开始:</span>${startD}</div>
  442. ${endD ? `<div class="fs-7"><span class="fw-bold">结束:</span>${endD}</div>` : ""}
  443. <div class="btn btn-sm btn-light-primary mt-3" id=${ClassName.BTN_MORE_VIEW} >查看更多</div>`
  444. };
  445. (popover = new KTApp.initBootstrapPopover(e, opt)).show();
  446. popoverIsInit = true;
  447. $(Selector.BTN_MORE_VIEW).on(`click${EVENT_KEY}`,
  448. (e) => {
  449. e.preventDefault();
  450. popoverDestroy();
  451. createViewModal();
  452. });
  453. };
  454. return {
  455. init: function(option) {
  456. option = option || {};
  457. $modal = option.modal ? (typeof option.modal == "string" ? $('#' + option.modal) : $(option.modal)) : $(Selector.MODAL);
  458. $form = $modal.find('form');
  459. today = moment().startOf("day");
  460. $(Selector.BTN_ADD).on(`click${EVENT_KEY}`,
  461. () => {
  462. add();
  463. });
  464. $form.find(Selector.FORM_ALL_DAY).on(`change${EVENT_KEY}`,
  465. (e) => {
  466. if (e.target.checked) {
  467. $(Selector.TIME).closest('.flex-column').addClass('d-none');
  468. } else {
  469. $(Selector.TIME).closest('.flex-column').removeClass('d-none');
  470. }
  471. });
  472. $fullCalendar = $(Selector.CALENDAR_BODY);
  473. (fullCalendar = new FullCalendar.Calendar($fullCalendar[0],
  474. {
  475. locale: window.lang,
  476. headerToolbar: {
  477. left: "prev,next today",
  478. center: "title",
  479. right: "dayGridMonth,timeGridWeek,timeGridDay"
  480. },
  481. initialDate: today.format("YYYY-MM-DD"),
  482. navLinks: true,
  483. selectable: true,
  484. selectMirror: true,
  485. editable: true,
  486. initialView: 'dayGridMonth',
  487. nowIndicator: true,
  488. dayMaxEvents: true,
  489. droppable: true,
  490. select: function(e) {
  491. popoverDestroy();
  492. convertData(e);
  493. add();
  494. },
  495. //eventDropStop: function (info) {
  496. // console.log("drop", info);
  497. // var event = info.event;
  498. // //event.start = info.date;
  499. // //event.allDay = info.allDay;
  500. // change(event, function () { abp.notify.success("设置成功!"); }, function () { fullCalendar.addEvent(info.oldEvent); });
  501. //},
  502. eventClick: function(e) {
  503. popoverDestroy();
  504. convertData({
  505. id: e.event.id,
  506. title: e.event.title,
  507. description: e.event.extendedProps.description,
  508. notifyType: e.event.extendedProps.notifyType,
  509. backgroundColor: e.event.backgroundColor,
  510. borderColor: e.event.borderColor,
  511. textColor: e.event.textColor,
  512. startStr: e.event.startStr,
  513. endStr: e.event.endStr,
  514. allDay: e.event.allDay
  515. });
  516. createViewModal();
  517. },
  518. eventMouseEnter: function(e) {
  519. convertData({
  520. id: e.event.id,
  521. title: e.event.title,
  522. description: e.event.extendedProps.description,
  523. notifyType: e.event.extendedProps.notifyType,
  524. backgroundColor: e.event.backgroundColor,
  525. borderColor: e.event.borderColor,
  526. textColor: e.event.textColor,
  527. startStr: e.event.startStr,
  528. endStr: e.event.endStr,
  529. allDay: e.event.allDay
  530. });
  531. popoverShow(e.el);
  532. },
  533. eventChange: function (info) {
  534. if (_triggerChangeEvent) {
  535. console.log("Change", info);
  536. change(info.event, function () { abp.notify.success("操作成功!"); }, function () { fullCalendar.addEvent(info.oldEvent); });
  537. }
  538. },
  539. events:loadEvent
  540. //[
  541. // {
  542. // id: "888",
  543. // title: "Reporting",
  544. // start: today.format("YYYY-MM") + "-13",
  545. // description: "xxx as ac vv bet gb tr rw nrn t",
  546. // //end: today.format("YYYY-MM") + "-14",
  547. // className: "fc-event-success",
  548. // allDay: true
  549. // }, {
  550. // id: "999",
  551. // title: "asd ff",
  552. // start: today.format("YYYY-MM") + "-14T14:00",
  553. // description: "xxx as ac vv bet gb tr rw nrn t",
  554. // end: today.format("YYYY-MM") + "-14T16:30",
  555. // className: "fc-event-success",
  556. // allDay: false
  557. // }
  558. //]
  559. }))
  560. .render();
  561. }
  562. }
  563. }();
  564. $(function() {
  565. VbCalendar.init({
  566. modal: "modal"
  567. });
  568. });
  569. </script>
  570. }