From 9da30eb5c203a65cc447e0bc1942f18758adee21 Mon Sep 17 00:00:00 2001 From: Dai Date: Sun, 14 Jul 2024 21:35:58 +0800 Subject: [PATCH] =?UTF-8?q?=E8=80=81=E5=B8=88=E5=90=8E=E5=8F=B0=E6=8E=92?= =?UTF-8?q?=E8=AF=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/TeacherFreeTimeController.php | 24 + app/common/model/TeacherFreeTime.php | 22 + app/common/service/TeacherFreeTimeService.php | 97 + .../controller/TeacherFreeTimeController.php | 116 + plugin/admin/app/model/TeacherFreeTime.php | 35 + .../teacher-free-time/free_time_setting.html | 189 + .../app/view/teacher-free-time/index.html | 306 + .../app/view/teacher-free-time/insert.html | 151 + .../view/teacher-free-time/update.bak.html | 189 + .../app/view/teacher-free-time/update.html | 291 + .../index.global.6.1.15.js | 19558 ++++++++++++++++ .../index.global.6.1.15.min.js | 6 + .../fullcalendar/index.global6.1.15.js | 14702 ++++++++++++ .../fullcalendar/index.global6.1.15.min.js | 6 + 14 files changed, 35692 insertions(+) create mode 100644 app/api/controller/TeacherFreeTimeController.php create mode 100644 app/common/model/TeacherFreeTime.php create mode 100644 app/common/service/TeacherFreeTimeService.php create mode 100644 plugin/admin/app/controller/TeacherFreeTimeController.php create mode 100644 plugin/admin/app/model/TeacherFreeTime.php create mode 100644 plugin/admin/app/view/teacher-free-time/free_time_setting.html create mode 100644 plugin/admin/app/view/teacher-free-time/index.html create mode 100644 plugin/admin/app/view/teacher-free-time/insert.html create mode 100644 plugin/admin/app/view/teacher-free-time/update.bak.html create mode 100644 plugin/admin/app/view/teacher-free-time/update.html create mode 100644 plugin/admin/public/resource/fullcalendar-scheduler/index.global.6.1.15.js create mode 100644 plugin/admin/public/resource/fullcalendar-scheduler/index.global.6.1.15.min.js create mode 100644 plugin/admin/public/resource/fullcalendar/index.global6.1.15.js create mode 100644 plugin/admin/public/resource/fullcalendar/index.global6.1.15.min.js diff --git a/app/api/controller/TeacherFreeTimeController.php b/app/api/controller/TeacherFreeTimeController.php new file mode 100644 index 0000000..da48bfd --- /dev/null +++ b/app/api/controller/TeacherFreeTimeController.php @@ -0,0 +1,24 @@ +addFreeTime($request); + return $this->json($res); + } + +} \ No newline at end of file diff --git a/app/common/model/TeacherFreeTime.php b/app/common/model/TeacherFreeTime.php new file mode 100644 index 0000000..a257738 --- /dev/null +++ b/app/common/model/TeacherFreeTime.php @@ -0,0 +1,22 @@ +teacher)) { + throw new Exception('请教师登陆后再设置'); + } + $teacher = Teacher::where(['id' => $request->teacher->id])->findOrEmpty(); + + if ($teacher->isEmpty()) { + throw new Exception('未找到教师信息,设置失败'); + } + +// $free_time = [ +// '2024-7-14'=>[ +// '9:00-10:00', +// '10:00-11:00', +// '11:00-12:00', +// ], +// '2024-7-15'=>[ +// '14:00-15:00', +// '15:00-16:00', +// '16:00-17:00', +// ], +// '2024-7-16'=>[ +// '9:00-10:00', +// '10:00-11:00', +// '11:00-12:00', +// ], +// '2024-7-17'=>[ +// '9:00-10:00', +// '10:00-11:00', +// '11:00-12:00', +// ] +// ]; + $data = $request->post(); + + $free_time = json_decode($data['free_time'], true); + + if (empty($free_time)) { + throw new Exception('请选择时间段之后再提交'); + } + foreach ($free_time as $free_date => $times) { + if ($times) { + foreach ($times as $time) { + $time_period = explode('-', $time); + $firstDate = new DateTime($free_date . ' ' . $time_period[0]); + $secondDate = new DateTime($free_date . ' ' . $time_period[1]); + $diff = $secondDate->diff($firstDate); + $h = $diff->h; + $m = round($diff->i / 60, 2); + $hour = round($h + $m, 2); + $free_data = [ + 'teacher_id' => $request->teacher->id, + 'date' => $free_date, + 'time' => $time, + 'hour' => $hour, + 'month' => date('Y-m', strtotime($free_date)), + ]; + $res = TeacherFreeTime::create($free_data); + if(!$res){ + throw new Exception('保存失败'); + } + } + } + } + + return [ + 'code' => ResponseCode::SUCCESS, + 'msg' => '保存成功' + ]; + } catch (Exception $e) { + return [ + 'code' => ResponseCode::FAIL, + 'msg' => $e->getMessage() + ]; + } + } + +} \ No newline at end of file diff --git a/plugin/admin/app/controller/TeacherFreeTimeController.php b/plugin/admin/app/controller/TeacherFreeTimeController.php new file mode 100644 index 0000000..f114d36 --- /dev/null +++ b/plugin/admin/app/controller/TeacherFreeTimeController.php @@ -0,0 +1,116 @@ +model = new TeacherFreeTime; + } + + /** + * 浏览 + * @return Response + */ + public function index(): Response + { + return view('teacher-free-time/index'); + } + + /** + * 插入 + * @param Request $request + * @return Response + * @throws BusinessException + */ + public function insert(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::insert($request); + } + return view('teacher-free-time/insert'); + } + + /** + * 更新 + * @param Request $request + * @return Response + * @throws BusinessException + */ + public function update(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::update($request); + } + return view('teacher-free-time/update'); + } + /** + * 更新 + * @param Request $request + * @return Response + * @throws BusinessException + */ + public function freeTimeSet(Request $request): Response + { + if ($request->method() === 'POST') { + return parent::update($request); + } + return view('teacher-free-time/free_time_setting'); + } + + /** + * @desc 时间列表 + * @param Request $request + * @return Response + */ + public function getFreeTime(Request $request) + { + try { + $list = \app\common\model\TeacherFreeTime::where(['teacher_id' => $request->get('id'), 'month' => '2024-07'])->select()->toArray(); + + $free_time = []; + foreach ($list as $item) { + $time_period = explode('-', $item['time']); + $free_time[] = [ + 'free_time_id'=> $item['id'], + 'title' => $item['time'], + 'start' => $item['date'] . ' ' . $time_period[0] + ]; + } + + return json([ + 'code' => ResponseCode::WEB_API_SUCCESS, + 'data' => $free_time, + 'msg' => 'success' + ]); + } catch (Exception $e) { + return json([ + 'code' => ResponseCode::WEB_API_FAIL, + 'msg' => $e->getMessage() + ]); + } + } + +} diff --git a/plugin/admin/app/model/TeacherFreeTime.php b/plugin/admin/app/model/TeacherFreeTime.php new file mode 100644 index 0000000..66c1598 --- /dev/null +++ b/plugin/admin/app/model/TeacherFreeTime.php @@ -0,0 +1,35 @@ + + + + + 更新页面 + + + + + + + +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+ + + + + + + + + + + diff --git a/plugin/admin/app/view/teacher-free-time/index.html b/plugin/admin/app/view/teacher-free-time/index.html new file mode 100644 index 0000000..dabd3ed --- /dev/null +++ b/plugin/admin/app/view/teacher-free-time/index.html @@ -0,0 +1,306 @@ + + + + + + 浏览页面 + + + + + + +
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ + + +
+
+ 展开 + 收起 +
+
+
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + + diff --git a/plugin/admin/app/view/teacher-free-time/insert.html b/plugin/admin/app/view/teacher-free-time/insert.html new file mode 100644 index 0000000..bb29eed --- /dev/null +++ b/plugin/admin/app/view/teacher-free-time/insert.html @@ -0,0 +1,151 @@ + + + + + 新增页面 + + + + + + +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+ + + + + + + + + + diff --git a/plugin/admin/app/view/teacher-free-time/update.bak.html b/plugin/admin/app/view/teacher-free-time/update.bak.html new file mode 100644 index 0000000..3cc8754 --- /dev/null +++ b/plugin/admin/app/view/teacher-free-time/update.bak.html @@ -0,0 +1,189 @@ + + + + + 更新页面 + + + + + + + +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+ + + + + + + + + + + diff --git a/plugin/admin/app/view/teacher-free-time/update.html b/plugin/admin/app/view/teacher-free-time/update.html new file mode 100644 index 0000000..a477387 --- /dev/null +++ b/plugin/admin/app/view/teacher-free-time/update.html @@ -0,0 +1,291 @@ + + + + + 更新页面 + + + + + + + + + + + +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+ + +
+
+ +
+ + + + + + + + + + + + diff --git a/plugin/admin/public/resource/fullcalendar-scheduler/index.global.6.1.15.js b/plugin/admin/public/resource/fullcalendar-scheduler/index.global.6.1.15.js new file mode 100644 index 0000000..aca902a --- /dev/null +++ b/plugin/admin/public/resource/fullcalendar-scheduler/index.global.6.1.15.js @@ -0,0 +1,19558 @@ +/*! +FullCalendar Premium Bundle v6.1.15 +Docs & License: https://fullcalendar.io/docs/initialize-globals +(c) 2024 Adam Shaw +*/ +var FullCalendar = (function (exports) { + 'use strict'; + + var n,l$1,u$1,i$1,t,r$1,o,f$1,e$1,c$1={},s=[],a$1=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function h(n,l){for(var u in l)n[u]=l[u];return n}function v$1(n){var l=n.parentNode;l&&l.removeChild(n);}function y(l,u,i){var t,r,o,f={};for(o in u)"key"==o?t=u[o]:"ref"==o?r=u[o]:f[o]=u[o];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),"function"==typeof l&&null!=l.defaultProps)for(o in l.defaultProps)void 0===f[o]&&(f[o]=l.defaultProps[o]);return p(l,f,t,r,null)}function p(n,i,t,r,o){var f={type:n,props:i,key:t,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++u$1:o};return null==o&&null!=l$1.vnode&&l$1.vnode(f),f}function d(){return {current:null}}function _(n){return n.children}function k$1(n,l,u,i,t){var r;for(r in u)"children"===r||"key"===r||r in l||g$2(n,r,null,u[r],i);for(r in l)t&&"function"!=typeof l[r]||"children"===r||"key"===r||"value"===r||"checked"===r||u[r]===l[r]||g$2(n,r,l[r],u[r],i);}function b$1(n,l,u){"-"===l[0]?n.setProperty(l,null==u?"":u):n[l]=null==u?"":"number"!=typeof u||a$1.test(l)?u:u+"px";}function g$2(n,l,u,i,t){var r;n:if("style"===l)if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof i&&(n.style.cssText=i=""),i)for(l in i)u&&l in u||b$1(n.style,l,"");if(u)for(l in u)i&&u[l]===i[l]||b$1(n.style,l,u[l]);}else if("o"===l[0]&&"n"===l[1])r=l!==(l=l.replace(/Capture$/,"")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+r]=u,u?i||n.addEventListener(l,r?w$2:m$1,r):n.removeEventListener(l,r?w$2:m$1,r);else if("dangerouslySetInnerHTML"!==l){if(t)l=l.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!==l&&"height"!==l&&"href"!==l&&"list"!==l&&"form"!==l&&"tabIndex"!==l&&"download"!==l&&l in n)try{n[l]=null==u?"":u;break n}catch(n){}"function"==typeof u||(null==u||!1===u&&-1==l.indexOf("-")?n.removeAttribute(l):n.setAttribute(l,u));}}function m$1(n){t=!0;try{return this.l[n.type+!1](l$1.event?l$1.event(n):n)}finally{t=!1;}}function w$2(n){t=!0;try{return this.l[n.type+!0](l$1.event?l$1.event(n):n)}finally{t=!1;}}function x$1(n,l){this.props=n,this.context=l;}function A(n,l){if(null==l)return n.__?A(n.__,n.__.__k.indexOf(n)+1):null;for(var u;ll&&r$1.sort(function(n,l){return n.__v.__b-l.__v.__b}));$$1.__r=0;}function H$1(n,l,u,i,t,r,o,f,e,a){var h,v,y,d,k,b,g,m=i&&i.__k||s,w=m.length;for(u.__k=[],h=0;h0?p(d.type,d.props,d.key,d.ref?d.ref:null,d.__v):d)){if(d.__=u,d.__b=u.__b+1,null===(y=m[h])||y&&d.key==y.key&&d.type===y.type)m[h]=void 0;else for(v=0;v=0;l--)if((u=n.__k[l])&&(i=L$1(u)))return i;return null}function M(n,u,i,t,r,o,f,e,c){var s,a,v,y,p,d,k,b,g,m,w,A,P,C,T,$=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(c=i.__h,e=u.__e=i.__e,u.__h=null,o=[e]),(s=l$1.__b)&&s(u);try{n:if("function"==typeof $){if(b=u.props,g=(s=$.contextType)&&t[s.__c],m=s?g?g.props.value:s.__:t,i.__c?k=(a=u.__c=i.__c).__=a.__E:("prototype"in $&&$.prototype.render?u.__c=a=new $(b,m):(u.__c=a=new x$1(b,m),a.constructor=$,a.render=B$1),g&&g.sub(a),a.props=b,a.state||(a.state={}),a.context=m,a.__n=t,v=a.__d=!0,a.__h=[],a._sb=[]),null==a.__s&&(a.__s=a.state),null!=$.getDerivedStateFromProps&&(a.__s==a.state&&(a.__s=h({},a.__s)),h(a.__s,$.getDerivedStateFromProps(b,a.__s))),y=a.props,p=a.state,a.__v=u,v)null==$.getDerivedStateFromProps&&null!=a.componentWillMount&&a.componentWillMount(),null!=a.componentDidMount&&a.__h.push(a.componentDidMount);else {if(null==$.getDerivedStateFromProps&&b!==y&&null!=a.componentWillReceiveProps&&a.componentWillReceiveProps(b,m),!a.__e&&null!=a.shouldComponentUpdate&&!1===a.shouldComponentUpdate(b,a.__s,m)||u.__v===i.__v){for(u.__v!==i.__v&&(a.props=b,a.state=a.__s,a.__d=!1),u.__e=i.__e,u.__k=i.__k,u.__k.forEach(function(n){n&&(n.__=u);}),w=0;w3;)e.pop()();if(e[1]>>1,1),e.i.removeChild(n);}}),D$1(y(P,{context:e.context},n.__v),e.l)):e.l&&e.componentWillUnmount();}function j(n,e){var r=y($,{__v:n,i:e});return r.containerInfo=e,r}(V.prototype=new x$1).__a=function(n){var t=this,e=F(t.__v),r=t.o.get(n);return r[0]++,function(u){var o=function(){t.props.revealOrder?(r.push(u),W(t,n,r)):u();};e?e(o):o();}},V.prototype.render=function(n){this.u=null,this.o=new Map;var t=j$2(n.children);n.revealOrder&&"b"===n.revealOrder[0]&&t.reverse();for(var e=t.length;e--;)this.o.set(t[e],this.u=[1,0,this.u]);return n.children},V.prototype.componentDidUpdate=V.prototype.componentDidMount=function(){var n=this;this.o.forEach(function(t,e){W(n,e,t);});};var z="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,B=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,H="undefined"!=typeof document,Z=function(n){return ("undefined"!=typeof Symbol&&"symbol"==typeof Symbol()?/fil|che|rad/i:/fil|che|ra/i).test(n)};x$1.prototype.isReactComponent={},["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach(function(t){Object.defineProperty(x$1.prototype,t,{configurable:!0,get:function(){return this["UNSAFE_"+t]},set:function(n){Object.defineProperty(this,t,{configurable:!0,writable:!0,value:n});}});});var G=l$1.event;function J(){}function K(){return this.cancelBubble}function Q(){return this.defaultPrevented}l$1.event=function(n){return G&&(n=G(n)),n.persist=J,n.isPropagationStopped=K,n.isDefaultPrevented=Q,n.nativeEvent=n};var nn={configurable:!0,get:function(){return this.class}},tn=l$1.vnode;l$1.vnode=function(n){var t=n.type,e=n.props,u=e;if("string"==typeof t){var o=-1===t.indexOf("-");for(var i in u={},e){var l=e[i];H&&"children"===i&&"noscript"===t||"value"===i&&"defaultValue"in e&&null==l||("defaultValue"===i&&"value"in e&&null==e.value?i="value":"download"===i&&!0===l?l="":/ondoubleclick/i.test(i)?i="ondblclick":/^onchange(textarea|input)/i.test(i+t)&&!Z(e.type)?i="oninput":/^onfocus$/i.test(i)?i="onfocusin":/^onblur$/i.test(i)?i="onfocusout":/^on(Ani|Tra|Tou|BeforeInp|Compo)/.test(i)?i=i.toLowerCase():o&&B.test(i)?i=i.replace(/[A-Z0-9]/g,"-$&").toLowerCase():null===l&&(l=void 0),/^oninput$/i.test(i)&&(i=i.toLowerCase(),u[i]&&(i="oninputCapture")),u[i]=l);}"select"==t&&u.multiple&&Array.isArray(u.value)&&(u.value=j$2(e.children).forEach(function(n){n.props.selected=-1!=u.value.indexOf(n.props.value);})),"select"==t&&null!=u.defaultValue&&(u.value=j$2(e.children).forEach(function(n){n.props.selected=u.multiple?-1!=u.defaultValue.indexOf(n.props.value):u.defaultValue==n.props.value;})),n.props=u,e.class!=e.className&&(nn.enumerable="className"in e,null!=e.className&&(u.class=e.className),Object.defineProperty(u,"className",nn));}n.$$typeof=z,tn&&tn(n);};var en=l$1.__r;l$1.__r=function(n){en&&en(n),n.__c;}; + + const styleTexts = []; + const styleEls = new Map(); + function injectStyles(styleText) { + styleTexts.push(styleText); + styleEls.forEach((styleEl) => { + appendStylesTo(styleEl, styleText); + }); + } + function ensureElHasStyles(el) { + if (el.isConnected && // sometimes true if SSR system simulates DOM + el.getRootNode // sometimes undefined if SSR system simulates DOM + ) { + registerStylesRoot(el.getRootNode()); + } + } + function registerStylesRoot(rootNode) { + let styleEl = styleEls.get(rootNode); + if (!styleEl || !styleEl.isConnected) { + styleEl = rootNode.querySelector('style[data-fullcalendar]'); + if (!styleEl) { + styleEl = document.createElement('style'); + styleEl.setAttribute('data-fullcalendar', ''); + const nonce = getNonceValue(); + if (nonce) { + styleEl.nonce = nonce; + } + const parentEl = rootNode === document ? document.head : rootNode; + const insertBefore = rootNode === document + ? parentEl.querySelector('script,link[rel=stylesheet],link[as=style],style') + : parentEl.firstChild; + parentEl.insertBefore(styleEl, insertBefore); + } + styleEls.set(rootNode, styleEl); + hydrateStylesRoot(styleEl); + } + } + function hydrateStylesRoot(styleEl) { + for (const styleText of styleTexts) { + appendStylesTo(styleEl, styleText); + } + } + function appendStylesTo(styleEl, styleText) { + const { sheet } = styleEl; + const ruleCnt = sheet.cssRules.length; + styleText.split('}').forEach((styleStr, i) => { + styleStr = styleStr.trim(); + if (styleStr) { + sheet.insertRule(styleStr + '}', ruleCnt + i); + } + }); + } + // nonce + // ------------------------------------------------------------------------------------------------- + let queriedNonceValue; + function getNonceValue() { + if (queriedNonceValue === undefined) { + queriedNonceValue = queryNonceValue(); + } + return queriedNonceValue; + } + /* + TODO: discourage meta tag and instead put nonce attribute on placeholder