",options:{disabled:!1,create:null},_createWidget:function(t,s){s=e(s||this.defaultElement||this)[0],this.element=e(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),s!==this&&(e.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===s&&this.destroy()}}),this.document=e(s.style?s.ownerDocument:s.document||s),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(i,s){var n,a,r,o=i;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof i)if(o={},n=i.split("."),i=n.shift(),n.length){for(a=o[i]=e.widget.extend({},this.options[i]),r=0;n.length-1>r;r++)a[n[r]]=a[n[r]]||{},a=a[n[r]];if(i=n.pop(),s===t)return a[i]===t?null:a[i];a[i]=s}else{if(s===t)return this.options[i]===t?null:this.options[i];o[i]=s}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,n){var a,r=this;"boolean"!=typeof i&&(n=s,s=i,i=!1),n?(s=a=e(s),this.bindings=this.bindings.add(s)):(n=s,s=this.element,a=this.widget()),e.each(n,function(n,o){function h(){return i||r.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?r[o]:o).apply(r,arguments):t}"string"!=typeof o&&(h.guid=o.guid=o.guid||h.guid||e.guid++);var l=n.match(/^(\w+)\s*(.*)$/),u=l[1]+r.eventNamespace,c=l[2];c?a.delegate(c,u,h):s.bind(u,h)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,r=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(r)&&r.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var r,o=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),r=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),r&&e.effects&&e.effects.effect[o]?s[t](n):o!==t&&s[o]?s[o](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}})})(jQuery);(function(e){var t=!1;e(document).mouseup(function(){t=!1}),e.widget("ui.mouse",{version:"1.10.2",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):undefined}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(i){if(!t){this._mouseStarted&&this._mouseUp(i),this._mouseDownEvent=i;var s=this,n=1===i.which,a="string"==typeof this.options.cancel&&i.target.nodeName?e(i.target).closest(this.options.cancel).length:!1;return n&&!a&&this._mouseCapture(i)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){s.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(i)&&this._mouseDelayMet(i)&&(this._mouseStarted=this._mouseStart(i)!==!1,!this._mouseStarted)?(i.preventDefault(),!0):(!0===e.data(i.target,this.widgetName+".preventClickEvent")&&e.removeData(i.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return s._mouseMove(e)},this._mouseUpDelegate=function(e){return s._mouseUp(e)},e(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),i.preventDefault(),t=!0,!0)):!0}},_mouseMove:function(t){return e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button?this._mouseUp(t):this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})})(jQuery);(function(e){e.widget("ui.draggable",e.ui.mouse,{version:"1.10.2",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"!==this.options.helper||/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(t){var i=this.options;return this.helper||i.disabled||e(t.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(t),this.handle?(e(i.iframeFix===!0?"iframe":i.iframeFix).each(function(){e("
").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var i=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),i.containment&&this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,i){if(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",t,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var i,s=this,n=!1,a=!1;for(e.ui.ddmanager&&!this.options.dropBehaviour&&(a=e.ui.ddmanager.drop(this,t)),this.dropped&&(a=this.dropped,this.dropped=!1),i=this.element[0];i&&(i=i.parentNode);)i===document&&(n=!0);return n||"original"!==this.options.helper?("invalid"===this.options.revert&&!a||"valid"===this.options.revert&&a||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,a)?e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){s._trigger("stop",t)!==!1&&s._clear()}):this._trigger("stop",t)!==!1&&this._clear(),!1):!1},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){return this.options.handle?!!e(t.target).closest(this.element.find(this.options.handle)).length:!0},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return s.parents("body").length||s.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s[0]===this.element[0]||/(fixed|absolute)/.test(s.css("position"))||s.css("position","absolute"),s},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&e.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var e=this.element.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,n=this.options;if("parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=["document"===n.containment?0:e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,"document"===n.containment?0:e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,("document"===n.containment?0:e(window).scrollLeft())+e("document"===n.containment?document:window).width()-this.helperProportions.width-this.margins.left,("document"===n.containment?0:e(window).scrollTop())+(e("document"===n.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||n.containment.constructor===Array)n.containment.constructor===Array&&(this.containment=n.containment);else{if(i=e(n.containment),s=i[0],!s)return;t="hidden"!==e(s).css("overflow"),this.containment=[(parseInt(e(s).css("borderLeftWidth"),10)||0)+(parseInt(e(s).css("paddingLeft"),10)||0),(parseInt(e(s).css("borderTopWidth"),10)||0)+(parseInt(e(s).css("paddingTop"),10)||0),(t?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(e(s).css("borderRightWidth"),10)||0)-(parseInt(e(s).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(e(s).css("borderBottomWidth"),10)||0)-(parseInt(e(s).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=i}},_convertPositionTo:function(t,i){i||(i=this.position);var s="absolute"===t?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():a?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():a?0:n.scrollLeft())*s}},_generatePosition:function(t){var i,s,n,a,o=this.options,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName),l=t.pageX,u=t.pageY;return this.originalPosition&&(this.containment&&(this.relative_container?(s=this.relative_container.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.left
i[2]&&(l=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(u=i[3]+this.offset.click.top)),o.grid&&(n=o.grid[1]?this.originalPageY+Math.round((u-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY,u=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-o.grid[1]:n+o.grid[1]:n,a=o.grid[0]?this.originalPageX+Math.round((l-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX,l=i?a-this.offset.click.left>=i[0]||a-this.offset.click.left>i[2]?a:a-this.offset.click.left>=i[0]?a-o.grid[0]:a+o.grid[0]:a)),{top:u-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:l-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(t,i,s){return s=s||this._uiHash(),e.ui.plugin.call(this,t,[i,s]),"drag"===t&&(this.positionAbs=this._convertPositionTo("absolute")),e.Widget.prototype._trigger.call(this,t,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,i){var s=e(this).data("ui-draggable"),n=s.options,a=e.extend({},i,{item:s.element});s.sortables=[],e(n.connectToSortable).each(function(){var i=e.data(this,"ui-sortable");i&&!i.options.disabled&&(s.sortables.push({instance:i,shouldRevert:i.options.revert}),i.refreshPositions(),i._trigger("activate",t,a))})},stop:function(t,i){var s=e(this).data("ui-draggable"),n=e.extend({},i,{item:s.element});e.each(s.sortables,function(){this.instance.isOver?(this.instance.isOver=0,s.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=this.shouldRevert),this.instance._mouseStop(t),this.instance.options.helper=this.instance.options._helper,"original"===s.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",t,n))})},drag:function(t,i){var s=e(this).data("ui-draggable"),n=this;e.each(s.sortables,function(){var a=!1,o=this;this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(a=!0,e.each(s.sortables,function(){return this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this!==o&&this.instance._intersectsWith(this.instance.containerCache)&&e.contains(o.instance.element[0],this.instance.element[0])&&(a=!1),a})),a?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=e(n).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return i.helper[0]},t.target=this.instance.currentItem[0],this.instance._mouseCapture(t,!0),this.instance._mouseStart(t,!0,!0),this.instance.offset.click.top=s.offset.click.top,this.instance.offset.click.left=s.offset.click.left,this.instance.offset.parent.left-=s.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=s.offset.parent.top-this.instance.offset.parent.top,s._trigger("toSortable",t),s.dropped=this.instance.element,s.currentItem=s.element,this.instance.fromOutside=s),this.instance.currentItem&&this.instance._mouseDrag(t)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",t,this.instance._uiHash(this.instance)),this.instance._mouseStop(t,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),s._trigger("fromSortable",t),s.dropped=!1)})}}),e.ui.plugin.add("draggable","cursor",{start:function(){var t=e("body"),i=e(this).data("ui-draggable").options;t.css("cursor")&&(i._cursor=t.css("cursor")),t.css("cursor",i.cursor)},stop:function(){var t=e(this).data("ui-draggable").options;t._cursor&&e("body").css("cursor",t._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,i){var s=e(i.helper),n=e(this).data("ui-draggable").options;s.css("opacity")&&(n._opacity=s.css("opacity")),s.css("opacity",n.opacity)},stop:function(t,i){var s=e(this).data("ui-draggable").options;s._opacity&&e(i.helper).css("opacity",s._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(){var t=e(this).data("ui-draggable");t.scrollParent[0]!==document&&"HTML"!==t.scrollParent[0].tagName&&(t.overflowOffset=t.scrollParent.offset())},drag:function(t){var i=e(this).data("ui-draggable"),s=i.options,n=!1;i.scrollParent[0]!==document&&"HTML"!==i.scrollParent[0].tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+i.scrollParent[0].offsetHeight-t.pageY=0;c--)r=p.snapElements[c].left,h=r+p.snapElements[c].width,l=p.snapElements[c].top,u=l+p.snapElements[c].height,g>r-m&&h+m>g&&y>l-m&&u+m>y||g>r-m&&h+m>g&&b>l-m&&u+m>b||v>r-m&&h+m>v&&y>l-m&&u+m>y||v>r-m&&h+m>v&&b>l-m&&u+m>b?("inner"!==f.snapMode&&(s=m>=Math.abs(l-b),n=m>=Math.abs(u-y),a=m>=Math.abs(r-v),o=m>=Math.abs(h-g),s&&(i.position.top=p._convertPositionTo("relative",{top:l-p.helperProportions.height,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:u,left:0}).top-p.margins.top),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r-p.helperProportions.width}).left-p.margins.left),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:h}).left-p.margins.left)),d=s||n||a||o,"outer"!==f.snapMode&&(s=m>=Math.abs(l-y),n=m>=Math.abs(u-b),a=m>=Math.abs(r-g),o=m>=Math.abs(h-v),s&&(i.position.top=p._convertPositionTo("relative",{top:l,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:u-p.helperProportions.height,left:0}).top-p.margins.top),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r}).left-p.margins.left),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:h-p.helperProportions.width}).left-p.margins.left)),!p.snapElements[c].snapping&&(s||n||a||o||d)&&p.options.snap.snap&&p.options.snap.snap.call(p.element,t,e.extend(p._uiHash(),{snapItem:p.snapElements[c].item})),p.snapElements[c].snapping=s||n||a||o||d):(p.snapElements[c].snapping&&p.options.snap.release&&p.options.snap.release.call(p.element,t,e.extend(p._uiHash(),{snapItem:p.snapElements[c].item})),p.snapElements[c].snapping=!1)}}),e.ui.plugin.add("draggable","stack",{start:function(){var t,i=this.data("ui-draggable").options,s=e.makeArray(e(i.stack)).sort(function(t,i){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(i).css("zIndex"),10)||0)});s.length&&(t=parseInt(e(s[0]).css("zIndex"),10)||0,e(s).each(function(i){e(this).css("zIndex",t+i)}),this.css("zIndex",t+s.length))}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,i){var s=e(i.helper),n=e(this).data("ui-draggable").options;s.css("zIndex")&&(n._zIndex=s.css("zIndex")),s.css("zIndex",n.zIndex)},stop:function(t,i){var s=e(this).data("ui-draggable").options;s._zIndex&&e(i.helper).css("zIndex",s._zIndex)}})})(jQuery);(function(e){function t(e){return parseInt(e,10)||0}function i(e){return!isNaN(parseInt(e,10))}e.widget("ui.resizable",e.ui.mouse,{version:"1.10.2",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_create:function(){var t,i,s,n,a,o=this,r=this.options;if(this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!r.aspectRatio,aspectRatio:r.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:r.helper||r.ghost||r.animate?r.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(e("
").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.data("ui-resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=r.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),t=this.handles.split(","),this.handles={},i=0;t.length>i;i++)s=e.trim(t[i]),a="ui-resizable-"+s,n=e("
"),n.css({zIndex:r.zIndex}),"se"===s&&n.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(n);this._renderAxis=function(t){var i,s,n,a;t=t||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=e(this.handles[i],this.element).show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(s=e(this.handles[i],this.element),a=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),t.css(n,a),this._proportionallyResize()),e(this.handles[i]).length},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){o.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),o.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){r.disabled||(e(this).removeClass("ui-resizable-autohide"),o._handles.show())}).mouseleave(function(){r.disabled||o.resizing||(e(this).addClass("ui-resizable-autohide"),o._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t,i=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),t=this.element,this.originalElement.css({position:t.css("position"),width:t.outerWidth(),height:t.outerHeight(),top:t.css("top"),left:t.css("left")}).insertAfter(t),t.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(t){var i,s,n=!1;for(i in this.handles)s=e(this.handles[i])[0],(s===t.target||e.contains(s,t.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(i){var s,n,a,o=this.options,r=this.element.position(),h=this.element;return this.resizing=!0,/absolute/.test(h.css("position"))?h.css({position:"absolute",top:h.css("top"),left:h.css("left")}):h.is(".ui-draggable")&&h.css({position:"absolute",top:r.top,left:r.left}),this._renderProxy(),s=t(this.helper.css("left")),n=t(this.helper.css("top")),o.containment&&(s+=e(o.containment).scrollLeft()||0,n+=e(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:s,top:n},this.size=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalSize=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalPosition={left:s,top:n},this.sizeDiff={width:h.outerWidth()-h.width(),height:h.outerHeight()-h.height()},this.originalMousePosition={left:i.pageX,top:i.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,a=e(".ui-resizable-"+this.axis).css("cursor"),e("body").css("cursor","auto"===a?this.axis+"-resize":a),h.addClass("ui-resizable-resizing"),this._propagate("start",i),!0},_mouseDrag:function(t){var i,s=this.helper,n={},a=this.originalMousePosition,o=this.axis,r=this.position.top,h=this.position.left,l=this.size.width,u=this.size.height,c=t.pageX-a.left||0,d=t.pageY-a.top||0,p=this._change[o];return p?(i=p.apply(this,[t,c,d]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(i=this._updateRatio(i,t)),i=this._respectSize(i,t),this._updateCache(i),this._propagate("resize",t),this.position.top!==r&&(n.top=this.position.top+"px"),this.position.left!==h&&(n.left=this.position.left+"px"),this.size.width!==l&&(n.width=this.size.width+"px"),this.size.height!==u&&(n.height=this.size.height+"px"),s.css(n),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),e.isEmptyObject(n)||this._trigger("resize",t,this.ui()),!1):!1},_mouseStop:function(t){this.resizing=!1;var i,s,n,a,o,r,h,l=this.options,u=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&e.ui.hasScroll(i[0],"left")?0:u.sizeDiff.height,a=s?0:u.sizeDiff.width,o={width:u.helper.width()-a,height:u.helper.height()-n},r=parseInt(u.element.css("left"),10)+(u.position.left-u.originalPosition.left)||null,h=parseInt(u.element.css("top"),10)+(u.position.top-u.originalPosition.top)||null,l.animate||this.element.css(e.extend(o,{top:h,left:r})),u.helper.height(u.size.height),u.helper.width(u.size.width),this._helper&&!l.animate&&this._proportionallyResize()),e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t,s,n,a,o,r=this.options;o={minWidth:i(r.minWidth)?r.minWidth:0,maxWidth:i(r.maxWidth)?r.maxWidth:1/0,minHeight:i(r.minHeight)?r.minHeight:0,maxHeight:i(r.maxHeight)?r.maxHeight:1/0},(this._aspectRatio||e)&&(t=o.minHeight*this.aspectRatio,n=o.minWidth/this.aspectRatio,s=o.maxHeight*this.aspectRatio,a=o.maxWidth/this.aspectRatio,t>o.minWidth&&(o.minWidth=t),n>o.minHeight&&(o.minHeight=n),o.maxWidth>s&&(o.maxWidth=s),o.maxHeight>a&&(o.maxHeight=a)),this._vBoundaries=o},_updateCache:function(e){this.offset=this.helper.offset(),i(e.left)&&(this.position.left=e.left),i(e.top)&&(this.position.top=e.top),i(e.height)&&(this.size.height=e.height),i(e.width)&&(this.size.width=e.width)},_updateRatio:function(e){var t=this.position,s=this.size,n=this.axis;return i(e.height)?e.width=e.height*this.aspectRatio:i(e.width)&&(e.height=e.width/this.aspectRatio),"sw"===n&&(e.left=t.left+(s.width-e.width),e.top=null),"nw"===n&&(e.top=t.top+(s.height-e.height),e.left=t.left+(s.width-e.width)),e},_respectSize:function(e){var t=this._vBoundaries,s=this.axis,n=i(e.width)&&t.maxWidth&&t.maxWidthe.width,r=i(e.height)&&t.minHeight&&t.minHeight>e.height,h=this.originalPosition.left+this.originalSize.width,l=this.position.top+this.size.height,u=/sw|nw|w/.test(s),c=/nw|ne|n/.test(s);return o&&(e.width=t.minWidth),r&&(e.height=t.minHeight),n&&(e.width=t.maxWidth),a&&(e.height=t.maxHeight),o&&u&&(e.left=h-t.minWidth),n&&u&&(e.left=h-t.maxWidth),r&&c&&(e.top=l-t.minHeight),a&&c&&(e.top=l-t.maxHeight),e.width||e.height||e.left||!e.top?e.width||e.height||e.top||!e.left||(e.left=null):e.top=null,e},_proportionallyResize:function(){if(this._proportionallyResizeElements.length){var e,t,i,s,n,a=this.helper||this.element;for(e=0;this._proportionallyResizeElements.length>e;e++){if(n=this._proportionallyResizeElements[e],!this.borderDif)for(this.borderDif=[],i=[n.css("borderTopWidth"),n.css("borderRightWidth"),n.css("borderBottomWidth"),n.css("borderLeftWidth")],s=[n.css("paddingTop"),n.css("paddingRight"),n.css("paddingBottom"),n.css("paddingLeft")],t=0;i.length>t;t++)this.borderDif[t]=(parseInt(i[t],10)||0)+(parseInt(s[t],10)||0);n.css({height:a.height()-this.borderDif[0]-this.borderDif[2]||0,width:a.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var t=this.element,i=this.options;this.elementOffset=t.offset(),this._helper?(this.helper=this.helper||e("
"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(e,t){return{width:this.originalSize.width+t}},w:function(e,t){var i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(e,t,i){return{height:this.originalSize.height+i}},se:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},sw:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,i,s]))},ne:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},nw:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,i,s]))}},_propagate:function(t,i){e.ui.plugin.call(this,t,[i,this.ui()]),"resize"!==t&&this._trigger(t,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","animate",{stop:function(t){var i=e(this).data("ui-resizable"),s=i.options,n=i._proportionallyResizeElements,a=n.length&&/textarea/i.test(n[0].nodeName),o=a&&e.ui.hasScroll(n[0],"left")?0:i.sizeDiff.height,r=a?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-o},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,u=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(e.extend(h,u&&l?{top:u,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};n&&n.length&&e(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(){var i,s,n,a,o,r,h,l=e(this).data("ui-resizable"),u=l.options,c=l.element,d=u.containment,p=d instanceof e?d.get(0):/parent/.test(d)?c.parent().get(0):d;p&&(l.containerElement=e(p),/document/.test(d)||d===document?(l.containerOffset={left:0,top:0},l.containerPosition={left:0,top:0},l.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}):(i=e(p),s=[],e(["Top","Right","Left","Bottom"]).each(function(e,n){s[e]=t(i.css("padding"+n))}),l.containerOffset=i.offset(),l.containerPosition=i.position(),l.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},n=l.containerOffset,a=l.containerSize.height,o=l.containerSize.width,r=e.ui.hasScroll(p,"left")?p.scrollWidth:o,h=e.ui.hasScroll(p)?p.scrollHeight:a,l.parentData={element:p,left:n.left,top:n.top,width:r,height:h}))},resize:function(t){var i,s,n,a,o=e(this).data("ui-resizable"),r=o.options,h=o.containerOffset,l=o.position,u=o._aspectRatio||t.shiftKey,c={top:0,left:0},d=o.containerElement;d[0]!==document&&/static/.test(d.css("position"))&&(c=h),l.left<(o._helper?h.left:0)&&(o.size.width=o.size.width+(o._helper?o.position.left-h.left:o.position.left-c.left),u&&(o.size.height=o.size.width/o.aspectRatio),o.position.left=r.helper?h.left:0),l.top<(o._helper?h.top:0)&&(o.size.height=o.size.height+(o._helper?o.position.top-h.top:o.position.top),u&&(o.size.width=o.size.height*o.aspectRatio),o.position.top=o._helper?h.top:0),o.offset.left=o.parentData.left+o.position.left,o.offset.top=o.parentData.top+o.position.top,i=Math.abs((o._helper?o.offset.left-c.left:o.offset.left-c.left)+o.sizeDiff.width),s=Math.abs((o._helper?o.offset.top-c.top:o.offset.top-h.top)+o.sizeDiff.height),n=o.containerElement.get(0)===o.element.parent().get(0),a=/relative|absolute/.test(o.containerElement.css("position")),n&&a&&(i-=o.parentData.left),i+o.size.width>=o.parentData.width&&(o.size.width=o.parentData.width-i,u&&(o.size.height=o.size.width/o.aspectRatio)),s+o.size.height>=o.parentData.height&&(o.size.height=o.parentData.height-s,u&&(o.size.width=o.size.height*o.aspectRatio))},stop:function(){var t=e(this).data("ui-resizable"),i=t.options,s=t.containerOffset,n=t.containerPosition,a=t.containerElement,o=e(t.helper),r=o.offset(),h=o.outerWidth()-t.sizeDiff.width,l=o.outerHeight()-t.sizeDiff.height;t._helper&&!i.animate&&/relative/.test(a.css("position"))&&e(this).css({left:r.left-n.left-s.left,width:h,height:l}),t._helper&&!i.animate&&/static/.test(a.css("position"))&&e(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),e.ui.plugin.add("resizable","alsoResize",{start:function(){var t=e(this).data("ui-resizable"),i=t.options,s=function(t){e(t).each(function(){var t=e(this);t.data("ui-resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};"object"!=typeof i.alsoResize||i.alsoResize.parentNode?s(i.alsoResize):i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):e.each(i.alsoResize,function(e){s(e)})},resize:function(t,i){var s=e(this).data("ui-resizable"),n=s.options,a=s.originalSize,o=s.originalPosition,r={height:s.size.height-a.height||0,width:s.size.width-a.width||0,top:s.position.top-o.top||0,left:s.position.left-o.left||0},h=function(t,s){e(t).each(function(){var t=e(this),n=e(this).data("ui-resizable-alsoresize"),a={},o=s&&s.length?s:t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var i=(n[t]||0)+(r[t]||0);i&&i>=0&&(a[t]=i||null)}),t.css(a)})};"object"!=typeof n.alsoResize||n.alsoResize.nodeType?h(n.alsoResize):e.each(n.alsoResize,function(e,t){h(e,t)})},stop:function(){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","ghost",{start:function(){var t=e(this).data("ui-resizable"),i=t.options,s=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),t.ghost.appendTo(t.helper)},resize:function(){var t=e(this).data("ui-resizable");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=e(this).data("ui-resizable");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(){var t=e(this).data("ui-resizable"),i=t.options,s=t.size,n=t.originalSize,a=t.originalPosition,o=t.axis,r="number"==typeof i.grid?[i.grid,i.grid]:i.grid,h=r[0]||1,l=r[1]||1,u=Math.round((s.width-n.width)/h)*h,c=Math.round((s.height-n.height)/l)*l,d=n.width+u,p=n.height+c,f=i.maxWidth&&d>i.maxWidth,m=i.maxHeight&&p>i.maxHeight,g=i.minWidth&&i.minWidth>d,v=i.minHeight&&i.minHeight>p;i.grid=r,g&&(d+=h),v&&(p+=l),f&&(d-=h),m&&(p-=l),/^(se|s|e)$/.test(o)?(t.size.width=d,t.size.height=p):/^(ne)$/.test(o)?(t.size.width=d,t.size.height=p,t.position.top=a.top-c):/^(sw)$/.test(o)?(t.size.width=d,t.size.height=p,t.position.left=a.left-u):(t.size.width=d,t.size.height=p,t.position.top=a.top-c,t.position.left=a.left-u)}})})(jQuery);
\ No newline at end of file
diff --git a/header.html b/header.html
new file mode 100644
index 0000000..68ab062
--- /dev/null
+++ b/header.html
@@ -0,0 +1,52 @@
+
+
+Work内部协作
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/img/cad.png b/img/cad.png
new file mode 100644
index 0000000..02cbd1e
Binary files /dev/null and b/img/cad.png differ
diff --git a/img/calendar-rest-bg.png b/img/calendar-rest-bg.png
new file mode 100644
index 0000000..66925ea
Binary files /dev/null and b/img/calendar-rest-bg.png differ
diff --git a/img/getcolor.png b/img/getcolor.png
new file mode 100644
index 0000000..924d4b8
Binary files /dev/null and b/img/getcolor.png differ
diff --git a/img/wekan-logo1.png b/img/wekan-logo1.png
new file mode 100644
index 0000000..147ce97
Binary files /dev/null and b/img/wekan-logo1.png differ
diff --git a/inc/appin.php b/inc/appin.php
new file mode 100644
index 0000000..353b87c
--- /dev/null
+++ b/inc/appin.php
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/inc/bll.php b/inc/bll.php
new file mode 100644
index 0000000..cd3a859
--- /dev/null
+++ b/inc/bll.php
@@ -0,0 +1,473 @@
+selectDB('wekan');
+
+
+
+//获取看板列表
+function getboards($userid=null,$archived=false){
+ global $MYID,$wekan;
+ if(isn($userid))$userid = $MYID;
+ $docs = $wekan->boards->find(array('members.userId'=>$MYID,'archived'=>$archived));
+ $res = iterator_to_array($docs);
+ return $res;
+}
+
+function getboardsByAdmin($admin){
+ global $MYID,$wekan;
+ if($admin=='all'){
+ $docs = $wekan->boards->find(array('archived'=>false));
+ }else{
+ $docs = $wekan->boards->find(array('org'=>$admin,'archived'=>false));
+ }
+ $res = iterator_to_array($docs);
+ return $res;
+}
+
+function getorgs(){
+ global $wekan;
+ $docs = $wekan->users->find(array(),array('org'=>1,'orgname'=>1));
+ $res = array();
+ $rss = iterator_to_array($docs);
+ foreach($rss as $rs){
+ $res[ $rs['org'] ] = $rs['orgname'];
+ }
+ return $res;
+}
+
+function getcards($boardid,$lists=null){
+ global $MYID,$wekan;
+
+ if($lists==null){
+ $docs = $wekan->cards->find(array('boardId'=>$boardid,'archived'=>false)); //'listId'=>$listid,
+ }else{
+ $docs = $wekan->cards->find(array('boardId'=>$boardid,'listId'=>array('$in'=>$lists),'archived'=>false));
+ }
+ $res = iterator_to_array($docs);
+ return $res;
+}
+
+
+function getmycards(){
+ global $MYID,$wekan;
+ $docs = $wekan->cards->find(array('members'=>$MYID,'archived'=>false)); //'listId'=>array('$in'=>$lists),
+ $res = iterator_to_array($docs);
+ return $res;
+}
+
+function getUserCards($uid, $st = null, $et = null)
+{
+ global $MYID, $wekan;
+
+ $mongostart = new MongoDate(strtotime($st));
+// $mongostart = new MongoDate(1546272000);
+
+ $mongoend = new MongoDate(strtotime($et));
+// $mongoend = new MongoDate(1548950400);
+
+
+ $docs = $wekan->cards->find(array(
+ 'members' => $uid,
+// "createdAt" => array('$gte' => $mongostart)
+// "createdAt" => array('$gte' => $mongostart, '$lte' => $mongoend)
+ "mem_time.{$uid}.start" => array('$gte' => strtotime($st)),
+ "mem_time.{$uid}.end" => array('$lte' => strtotime($et))
+ )
+ ); //'listId'=>array('$in'=>$lists),
+ $res = iterator_to_array($docs);
+ return $res;
+}
+
+// 某个用户完成的单子
+function getUserCards4Finish($uid, $st = null, $et = null)
+{
+ global $MYID, $wekan;
+
+ $mongostart = new MongoDate(strtotime($st));
+// $mongostart = new MongoDate(1546272000);
+
+ $mongoend = new MongoDate(strtotime($et));
+// $mongoend = new MongoDate(1548950400);
+
+
+ $docs = $wekan->cards->find(array(
+ 'members' => $uid,
+ '$or'=>array(
+ array(
+ //'qalabelIds'=>'gongnengyanfa',
+ "mem_time.{$uid}.start" => array('$gte' => strtotime($st)),
+ "mem_time.{$uid}.end" => array('$lte' => strtotime($et))
+ ),
+ array(
+ //'qalabelIds'=>array('$ne'=>'gongnengyanfa'),
+ "finishAt" => array('$gte' => strtotime($st),'$lte' => strtotime($et)),
+ ),
+ ),
+// "createdAt" => array('$gte' => $mongostart)
+// "createdAt" => array('$gte' => $mongostart, '$lte' => $mongoend)
+ )
+ ); //'listId'=>array('$in'=>$lists),
+ $res = iterator_to_array($docs);
+
+ $arr = array();
+ foreach($res as $id=>$val){
+ $qalabelIds = array();
+ if($val['qalabelIds']){
+ $qalabelIds = $val['qalabelIds'];
+ }
+ if( in_array('gongnengyanfa',$qalabelIds) ){
+ //功能研发单,则判断标记时间
+ if( $val['mem_time'][$uid] && $val['mem_time'][$uid]['start']>=strtotime($st) && $val['mem_time'][$uid]['end']<=strtotime($et) ){
+
+ }else{
+ continue;
+ }
+ }
+ $arr[$id] = $val;
+ }
+ return $arr;
+}
+
+function getUserCards4New($uid, $st = null, $et = null)
+{
+ global $MYID, $wekan;
+
+ $mongostart = new MongoDate(strtotime($st));
+ $mongoend = new MongoDate(strtotime($et));
+
+ $docs = $wekan->cards->find(array(
+ 'members' => $uid,
+ "createdAt" => array('$gte' => ($mongostart),'$lte' => ($mongoend))
+ ));
+ $res = iterator_to_array($docs);
+ return $res;
+}
+
+
+function getcard($cardid){
+ global $MYID,$wekan;
+// $docs = $wekan->cards->find(array('_id'=>$cardid,'archived'=>false)); //'listId'=>$listid,
+ $docs = $wekan->cards->find(array('_id'=>$cardid)); //'listId'=>$listid,
+ $res = iterator_to_array($docs);
+ return $res;
+}
+
+
+function getboardsettingcard($boardid,$cardtitle){
+ global $MYID,$wekan;
+ $cardtitle = "__setting.".$cardtitle;
+ $docs = $wekan->cards->find(array('boardId'=>$boardid,'title'=>$cardtitle,'archived'=>false)); //'listId'=>$listid,
+ $res = iterator_to_array($docs);
+
+ return $res;
+}
+
+function getlists($boardid){
+ global $MYID,$wekan;
+ $docs = $wekan->lists->find(array('boardId'=>$boardid,'archived'=>false));
+ $res = iterator_to_array($docs);
+ return $res;
+}
+function getlist($listid){
+ global $MYID,$wekan;
+ $docs = $wekan->lists->find(array('_id'=>$listid));
+ $res = iterator_to_array($docs);
+ return $res;
+}
+
+function getBoard($boardid){
+ global $MYID,$wekan;
+ $docs = $wekan->boards->find(array('_id'=>$boardid));
+ $res = iterator_to_array($docs);
+ return $res;
+}
+
+function getusers(){
+ global $MYID,$wekan;
+ if(isn($userid))$userid = $MYID;
+ $docs = $wekan->users->find(array(), array(
+ 'username' => true,
+ 'emails' => true,
+ 'org'=>true,
+ 'orgname'=>true,
+ 'dduserid'=>true,
+ 'profile.fullname' => true,
+ 'profile.avatarUrl' => true,
+ 'legulabel'=>true,
+ 'legugroup'=>true,
+ 'lastlogin'=>true,
+ ));
+ $res = iterator_to_array($docs);
+ return $res;
+}
+
+function getUserInfo($userid){
+ global $MYID,$wekan;
+ $docs = $wekan->users->find(array("_id"=>$userid));
+ $res = iterator_to_array($docs);
+ return $res[$userid];
+}
+
+function getcard_comments($cardid){
+ global $MYID,$wekan;
+ $docs = $wekan->card_comments->find(array('cardId'=>$cardid))->sort(array('createdAt'=>-1));
+ $res = iterator_to_array($docs);
+ return $res;
+}
+
+
+function initLables(){
+ $labels = array(
+ array(
+ "color" =>"legublue",
+ "name" =>"策"
+ ),
+ array(
+ "color" =>"legublue",
+ "name" =>"策配"
+ ),
+ array(
+ "color" =>"legublue",
+ "name" =>"策验"
+ ),
+ array(
+ "color" =>"legublue",
+ "name" =>"审UI"
+ ),
+ array(
+ "color" =>"legured",
+ "name" =>"前程"
+ ),
+ array(
+ "color" =>"legured",
+ "name" =>"后程"
+ ),
+ array(
+ "color" =>"legupurple",
+ "name" =>"UI"
+ ),
+ array(
+ "color" =>"legupurple",
+ "name" =>"UI验"
+ ),
+ array(
+ "color" =>"leguyellow",
+ "name" =>"美"
+ ),
+ array(
+ "color" =>"legugreen",
+ "name" =>"美验"
+ ),
+ array(
+ "color" =>"legublue",
+ "name" =>"动效"
+ ),
+ array(
+ "color" =>"legured",
+ "name" =>"动验"
+ ),
+ array(
+ "color" =>"legupink",
+ "name" =>"QA"
+ ),
+ array(
+ "color" =>"legugray",
+ "name" =>"运营"
+ ),
+ array(
+ "color" =>"legugray",
+ "name" =>"打包"
+ )
+ );
+
+
+ foreach($labels as $idx => $label){
+ $labels[$idx]['_id'] = uniqid().$idx;
+ }
+
+ //return $labels;
+ return array();
+}
+
+function getAllRiskLabels(){
+ global $MYID,$wekan;
+ $docs = $wekan->risktags->find(array(), array(
+ '_id' => false,
+ 'issueId' => true,
+ 'tagId' => true,
+ 'tag' => true,
+ 'reasonTag' => true,
+ 'color' => true,
+ 'description' => true,
+ 'reason'=>true,
+ 'department'=>true,
+ 'issueColor'=>issueColor
+ ));
+
+ $labels = iterator_to_array($docs);
+
+ $res = array();
+ foreach($labels as $val){
+ $res[ $val['tagId'] ][] = $val;
+ }
+
+ return $res;
+}
+
+function getRiskLabels(){
+ global $MYID,$wekan;
+ $labels = $wekan->command (
+ array(
+ "aggregate" => "risktags",
+ "pipeline" =>
+ array(
+ array( '$group' => array( "_id" => ['_id' =>'$tagId', 'name' => '$tag', 'color' => '$color'])),
+ array( '$replaceRoot' => array( "newRoot" => '$_id' ))
+ ),
+ "cursor" => ['batchSize' => 200]
+ )
+ );
+ $res = array();
+
+ foreach($labels['cursor']['firstBatch'] as $val){
+ $res[ $val['_id'] ] = $val;
+ }
+ return $res;
+}
+
+function initQALables(){
+ $labels = array(
+ array(
+ "_id"=>"bug",
+ "color" =>"legured",
+ "name" =>"BUG"
+ ),
+ array(
+ "_id"=>"ziyuanqueshi",
+ "color" =>"leguyellow",
+ "name" =>"资源缺失"
+ ),
+ array(
+ "_id"=>"geleiyouhua",
+ "color" =>"legublue",
+ "name" =>"各类优化"
+ ),
+ array(
+ "_id"=>"gongnengyanfa",
+ "color" =>"leguaqua",
+ "name" =>"功能研发"
+ ),
+ array(
+ "_id"=>"xingnengyouhua",
+ "color" =>"legupurple",
+ "name" =>"性能问题"
+ ),
+ array(
+ "_id"=>"qita",
+ "color" =>"legugray",
+ "name" =>"其他"
+ ),
+
+ );
+
+
+// foreach($labels as $idx => $label){
+// $labels[$idx]['_id'] = uniqid().$idx;
+// }
+
+ //return $labels;
+ return array();
+}
+
+function eventData($act,$data){
+ return json_encode(array(
+ "_k"=>"EVENT",
+ "act"=>$act,
+ "data" => $data,
+ ));
+}
+
+// 根据boardId获取看板的标签的名字数组 _id=>name
+function getBoardLabelIdNames($boardId){
+ global $wekan;
+ $resBoards = $wekan->boards->find(array(
+ "archived" => false,
+ "_id" => $boardId,
+ ));
+ $boardData = iterator_to_array($resBoards);
+ $board = $boardData[$boardId];
+ $boardLabels = $board['labels'];
+ $boardLabelArr = array();
+ foreach ($boardLabels as $label){
+ $boardLabelArr[$label['_id']] = $label['name'];
+ }
+ return $boardLabelArr;
+}
+
+// 获取延期列表数据 部门对应用户
+// 5ce68e49bd298
+function getYanQiDepartmentUser(){
+ global $MYID,$wekan,$LEGUWORK_SETTING_LISTID,$LEGUWORK_BOARDID,$LEGUWORK_YANQI_LISTID;
+
+ $cardData = $wekan->cards->find(array('archived'=>false,'boardId'=>$LEGUWORK_BOARDID,'listId'=>$LEGUWORK_YANQI_LISTID));
+ $cardData = iterator_to_array($cardData);
+
+ $boardData = $wekan->boards->findOne(array(
+ "_id" => $LEGUWORK_BOARDID,
+ ));
+
+ $boardLabels = $boardData['labels'];
+ $labelNameIdArr = array();
+ $labelIdNameArr = array();
+ foreach ($boardLabels as $k => $v) {
+ $labelNameIdArr[$v['name']] = $v['_id'];
+ $labelIdNameArr[$v['_id']] = $v['name'];
+ }
+
+ $labelUserArr = array();
+ $labelIdUserArr = array();
+ foreach ($cardData as $k => $v) {
+ // 延期成员在的部门
+ $labelIds = $v['labelIds'];
+ $members = $v['members'];
+
+// var_dump($members);
+
+ foreach ($labelIds as $labelID) {
+ $labelIdUserArr[$labelID] = array(
+ 'name'=>$labelIdNameArr[$labelID],
+ 'user'=>$members
+ );
+ }
+ }
+
+ return $labelIdUserArr;
+
+}
+
+
+
+$MYID = $_SESSION['leguworkUID']; //;// 'NNCQpGcDX9L2EexLQ';//
+$LEGUWORKUSER = $_SESSION['leguworkUser'];
+$DTALK_APPID = "";
+if($LEGUWORKUSER){
+ $DTALK_APPID = $LEGUWORKUSER['appid'];
+}
+?>
\ No newline at end of file
diff --git a/inc/cache.inc.php b/inc/cache.inc.php
new file mode 100644
index 0000000..942932f
--- /dev/null
+++ b/inc/cache.inc.php
@@ -0,0 +1,175 @@
+start();
+*
+* # Your Page Contents With print
+* phpinfo();
+*
+* $cache->_end();
+*
+*/
+
+class fileCache {
+ var $_file;
+ var $cache_time;
+
+ function fileCache($_file='_index.htm',$cache_time=1) {
+ $this->_file = $_file;
+ $this->cache_time = $cache_time;
+ }
+ /*
+ * Start cache method without return
+ */
+ function start() {
+ if($this->cache_is_active()) {
+ include($this->_file);
+ exit;
+ }
+ ob_start();
+ }
+
+ /*
+ * End of cache method without Return
+ */
+ function _end() {
+ $this->make_cache();
+ ob_end_flush();
+ }
+
+ /*
+ * Check if cache file is actived
+ * Return true/false
+ */
+ function cache_is_active() {
+ if ($this->cache_is_exist()) {
+ if (time() - $this->lastModified() < $this->cache_time)
+ return true;
+ else {
+ return false;
+ }
+ }
+ else {
+ return false;
+ }
+ }
+
+ /*
+ * Create cache file
+ * return true/false
+ */
+ function make_cache() {
+ $content = $this->get_cache_content();
+ $content = str_replace(array("\r","\n","\t"),'',$content);
+ if($this->write_file($content)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ /*
+ * Check if cache file is exists
+ * return true/false
+ */
+ function cache_is_exist() {
+ if(file_exists($this->_file)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ /*
+ * return last Modified time in bollin formart
+ * Usage: $lastmodified = $this->lastModified();
+ */
+ function lastModified() {
+ return @filemtime($this->_file);
+ }
+
+ /*
+ * return Content of Page
+ * Usage: $content = $this->get_cache_content();
+ */
+ function get_cache_content() {
+ $contents = ob_get_contents();
+// return ''.$contents;
+ return $contents;
+ }
+
+ /*Write content to $this->_file
+ * return true/false
+ * Usage: $this->write_file($content);
+ **/
+ function write_file($content,$mode='w+')
+ {
+ $this->mk_dir($this->_file);
+ if (!$fp = @fopen($this->_file,$mode)) {
+ $this->report_Error($this->_file." 目录或者文件属性无法写入.");
+ return false;
+ } else{
+ @fwrite($fp,$content);
+ @fclose($fp);
+ @umask($oldmask);
+ return true;
+ }
+ }
+
+ /*
+ * Make given dir included in $this->_file
+ * Without return
+ * Usage: $this->mk_dir();
+ */
+ function mk_dir()
+ { //$this->_file = str_replace('','/');
+ $dir = @explode("/", $this->_file);
+ $num = @count($dir)-1;
+ $tmp = './';
+ for($i=0; $i<$num; $i++){
+ $tmp .= $dir[$i];
+ if(!file_exists($tmp)){
+ @mkdir($tmp);
+ @chmod($tmp, 0777);
+ }
+ $tmp .= '/';
+ }
+ }
+
+ /*
+ * Unlink an exists cache
+ * return true/false
+ * Usage: $this->clear_cache();
+ */
+ function clear_cache() {
+ if (!@unlink($this->_file)) {
+ $this->report_Error('Unable to remove cache');
+ return false;
+ }
+ else {
+ return true;
+ }
+ }
+ /*
+ * Report Error Messages
+ * Usage: $this->report_Error($message);
+ */
+ function report_Error($message=NULL) {
+ if($message!=NULL) {
+ trigger_error($message);
+ }
+ }
+}
+?>
diff --git a/inc/common.php b/inc/common.php
new file mode 100644
index 0000000..697e751
--- /dev/null
+++ b/inc/common.php
@@ -0,0 +1,714 @@
+ $val) {
+ $string[$key] = sqlEncode($val);
+ }
+ } else {
+ $string = addslashes($string);
+ }
+ return $string;
+}
+
+//去掉SQL编码
+function sqlDecode($string) {
+ if(is_array($string)) {
+ foreach($string as $key => $val) {
+ $string[$key] = sqlDecode($val);
+ }
+ } else {
+ $string = stripslashes($string);
+ }
+ return $string;
+}
+
+//将对象全部转换成数组
+function deObject2Array($obj){
+ if(gettype($obj) == object)
+ $obj = get_object_vars($obj);
+
+ if(count($obj) > 0)
+ {
+ foreach($obj as $k=>$v){
+ if(gettype($v) == object){
+ $obj[$k] = deObject2Array($v);
+ }
+ }
+ }
+ return $obj;
+}
+
+//HTML代码编码
+function htmlEncode($string) {
+ if(is_array($string)) {
+ foreach($string as $key => $val) {
+ $string[$key] = shtmlspecialchars($val);
+ }
+ } else {
+ $string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4})|[a-zA-Z][a-z0-9]{2,5});)/', '&\\1',
+ str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string));
+ }
+ return $string;
+}
+
+function myjson_encode($code){
+ $code = json_encode($code);
+ return preg_replace("#\\\u([0-9a-f]{4,4})#ie", "iconv('UCS-2', 'UTF-8', pack('H4', '\\1'))", $code);
+}
+
+function myjson_decode($code){
+ $code = json_decode($code);
+ return preg_replace("#\\\u([0-9a-f]{4,4})#ie", "iconv('UCS-2', 'UTF-8', pack('H4', '\\1'))", $code);
+}
+
+//获取文件内容
+function getFile($filename,$clearBOM=1){
+ $content = '';
+ if(function_exists('file_get_contents')) {
+ @$content = file_get_contents($filename);
+ } else {
+ if(@$fp = fopen($filename, 'r')) {
+ @$content = fread($fp, filesize($filename));
+ @fclose($fp);
+ }
+ }
+ //清除BOM信息
+ if($clearBOM==1){
+ $charset[1]=substr($content, 0, 1);
+ $charset[2]=substr($content, 1, 1);
+ $charset[3]=substr($content, 2, 1);
+ if (ord($charset[1])==239 && ord($charset[2])==187 && ord($charset[3])==191) {
+ $content=substr($content,3);
+ }
+ }
+ return $content;
+}
+
+//写入文件
+function setFile($filename, $writetext, $openmod='w') {
+ if(@$fp = fopen($filename, $openmod)) {
+ flock($fp, 2);
+ fwrite($fp, $writetext);
+ fclose($fp);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+//字符串解密加密
+function aen($string, $operation = 'DECODE', $key = '', $expiry = 0) {
+ $ckey_length = 4;
+ // 随机密钥长度 取值 0-32;
+ // 加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。
+ // 取值越大,密文变动规律越大,密文变化 = 16 的 $ckey_length 次方
+ // 当此值为 0 时,则不产生随机密钥
+ $key = md5($key ? $key : 'IAmCiNiao!!!');
+ $keya = md5(substr($key, 0, 16));
+ $keyb = md5(substr($key, 16, 16));
+ $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
+
+ $cryptkey = $keya.md5($keya.$keyc);
+ $key_length = strlen($cryptkey);
+
+ $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
+ $string_length = strlen($string);
+
+ $result = '';
+ $box = range(0, 255);
+
+ $rndkey = array();
+ for($i = 0; $i <= 255; $i++) {
+ $rndkey[$i] = ord($cryptkey[$i % $key_length]);
+ }
+
+ for($j = $i = 0; $i < 256; $i++) {
+ $j = ($j + $box[$i] + $rndkey[$i]) % 256;
+ $tmp = $box[$i];
+ $box[$i] = $box[$j];
+ $box[$j] = $tmp;
+ }
+
+ for($a = $j = $i = 0; $i < $string_length; $i++) {
+ $a = ($a + 1) % 256;
+ $j = ($j + $box[$a]) % 256;
+ $tmp = $box[$a];
+ $box[$a] = $box[$j];
+ $box[$j] = $tmp;
+ $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
+ }
+
+ if($operation == 'DECODE') {
+ if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
+ return substr($result, 26);
+ } else {
+ return '';
+ }
+ } else {
+ return $keyc.str_replace('=', '', base64_encode($result));
+ }
+}
+
+//抓取数据方法封装
+/*
+$url : 抓取的url路径
+$postArray : POST的数据,默认为空
+$con : 更多设置,array(CURLOPT_COOKIE=>'cookname=cookval&cn2=cv2')
+*/
+function getHttpPage($url,$postArray='',$con=''){
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ //curl_setopt($ch, CURLOPT_TIMEOUT, 10000); //超时时间(秒)
+ if(is_array($postArray)){
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS,$postArray);
+ }
+ if(is_array($con)){
+ foreach($con as $key => $value){
+ curl_setopt($ch,$key,$value);
+ }
+ }
+ $html = curl_exec($ch);
+ curl_close($ch);
+ return $html;
+}
+
+//检查邮箱是否有效
+function isEmail($email) {
+ return strlen($email) > 6 && preg_match("/^[\w\-\.]+@[\w\-\.]+(\.\w+)+$/", $email);
+}
+
+//当前时间
+function now(){
+ return date("Y-m-d H:i:s");
+}
+
+/*
+取字符串左右
+left('abcde',-1) = abcd
+*/
+function left($str,$len){
+ if((int)$len>0){
+ return mb_substr($str,0,$len,'utf8');
+ }else{
+ return mb_substr($str,0,len($str)+$len,'utf8');
+ }
+}
+function right($str,$len){
+ if($len>0){
+ return mb_substr($str,len($str)-$len,len($str),'utf8');
+ }else{
+ return mb_substr($str,abs($len),len($str),'utf8');
+ }
+}
+function len($str){
+ return mb_strlen($str,'utf8');
+}
+
+/*
+字符串查找,同JS中的indexOf
+未找到返回 -1 (被查找的字符串,要查找的,从前还是后:默认前)
+*/
+function indexOf($str,$find,$rev=0){
+ if($rev==0){
+ $res=stripos($str,$find);
+ }else{
+ $res=strripos($str,$find);
+ }
+ if(isn($res)){
+ return -1;
+ }else{
+ return $res;
+ }
+}
+
+//跳转到指定页面
+function jsgoto($url){
+ header("refresh:0;url=$url");
+ echo "";
+}
+
+//判断是否为空值
+function isn($str){
+ if(is_array($str)){
+ return 0;
+ }
+ if(is_null($str) || strlen($str)==0){
+ return 1;
+ }else{
+ return 0;
+ }
+}
+
+//获取客户端IP
+function getip(){
+ if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
+ $onlineip = getenv('HTTP_CLIENT_IP');
+ } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
+ $onlineip = getenv('HTTP_X_FORWARDED_FOR');
+ } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
+ $onlineip = getenv('REMOTE_ADDR');
+ } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
+ $onlineip = $_SERVER['REMOTE_ADDR'];
+ }
+ return $onlineip;
+}
+//是否数字简写
+function isNum($str){
+ $isnum = 0;
+ if(is_numeric($str)) $isnum = 1;
+ return $isnum;
+}
+
+//替代die函数
+function we($str){
+ if(gettype($str)=='string'){
+ echo $str;
+ }else{
+ print_r($str);
+ }
+ global $mongo;
+ $mongo->close();
+ exit;
+}
+
+//Request方法简写
+function rq($name){
+ return $_GET[$name];
+}
+function rf($name){
+ return $_POST[$name];
+}
+function r($name){
+ return $_REQUEST[$name];
+}
+function _rq($name){
+ return sqlDecode(rq($name));
+}
+function _rf($name){
+ return sqlDecode(rf($name));
+}
+function _r($name){
+ return sqlDecode(r($name));
+}
+
+//获取当前周的第一天的日期时间戳
+function getWeekStartTime($date){
+ $ntime=strtotime($date);
+ $week = date('W',$ntime);
+ $dayNum = 0;
+ for($i = 1;$i<8;$i++){
+ $difTime = date('W',strtotime(date("Ymd",$ntime))-(60*60*24*$i));
+ if($week == $difTime)
+ $dayNum++;
+ }
+
+ $weekStart = strtotime(date("Ymd",$ntime))-(60*60*24*$dayNum);
+ return $weekStart;
+}
+
+//时间相加
+function dateAdd($unit = "d",$int,$date) {
+ $date_time_array = getdate(strtotime($date));
+ $hours = $date_time_array["hours"];
+ $minutes = $date_time_array["minutes"];
+ $seconds = $date_time_array["seconds"];
+ $month = $date_time_array["mon"];
+ $day = $date_time_array["mday"] ;
+ $year = $date_time_array["year"] ;
+ switch ($unit) {
+ case "yyyy": $year +=$int;
+ break;
+ case "q": $month +=($int*3);
+ break;
+ case "m": $month +=$int;
+ break;
+ case "y": $day+=$int;
+ break;
+ case "d": $day+=$int;
+ break;
+ case "w": $day+=$int;
+ break;
+ case "ww": $day+=($int*7);
+ break;
+ case "h": $hours+=$int;
+ break;
+ case "n": $minutes+=$int;
+ break;
+ case "s": $seconds+=$int;
+ break;
+ }
+ $timestamp = mktime($hours ,$minutes, $seconds,$month ,$day, $year);
+ return date("Y-m-d H:i:s",$timestamp);
+}
+
+##SQL语句类
+class DB{
+ public static $conns = array();
+ /*
+ 取得数据库连接资源
+ 从serverconfig中载入$_CONFIG['db']配置项
+ */
+ public function getconnG(){
+ global $_CONFIG;
+ return self::conndb($_CONFIG['db']);
+ }
+ /*
+ 连接数据库,配置文件格式
+ array(
+ 'ip'=>'localhost', #数据库服务器IP
+ 'username'=>'root', #用户名
+ 'pwd'=>'root', #密码
+ 'database'=>'game3', #数据库名
+ 'charset'=>'utf8', #默认编码
+ )
+ */
+ public function conndb($dbconf){
+ $key = $dbconf['database'] .'_'. $dbconf['username'] .'_'. $dbconf['pwd'];
+ if(self::$conns[$key]){
+ return self::$conns[$key];
+ }
+
+ $conn = @mysql_connect($dbconf['ip'].($dbconf['port'] && $dbconf['port']!=''?':'.$dbconf['port']:''), $dbconf['username'], $dbconf['pwd']);
+ if(!$conn)self::error("数据库服务器连接超时");
+ $db = @mysql_select_db($dbconf['database'],$conn);
+ if(!$db)self::error("{$dbconf['database']}读取错误");
+ mysql_query("SET NAMES '".$dbconf['charset']."'",$conn);
+ self::$conns[$key]=$conn;
+ return $conn;
+ }
+
+ /*关闭数据库*/
+ public function closeall(){
+ foreach(self::$conns as $key=>$val){
+ @mysql_close($val);
+ @mysql_free_result();
+ self::$conns = array();
+ }
+ }
+
+ /*返回数据库记录集*/
+ public function exe($sql){
+ if($sql=='') self::error('exe时SQL语句必须存在');
+ $conn = self::getconnG();
+ $res = @mysql_query($sql,$conn);
+ if(mysql_error($conn)) self::error();
+ return $res;
+ unset($res,$conn);
+ }
+
+ /*
+ 事务方式执行SQL语句,sql可以是字符串或数组
+ 多条SQL语句以 ; 号切分,语句中不得含有;号
+ */
+ public function exesql($sql,$count=false){
+ if(isn($sql)) self::error('EXESQL时SQL语句必须存在');
+
+ global $exesqlCount;
+ $errnum = 0; $errorTxt = '';
+ $exesqlCount = array();
+
+ if(is_array($sql)){
+ $sql = implode($sql,';');
+ }
+ $sqlArr = split (';',$sql);
+
+ $conn = self::getconnG();
+ mysql_query('BEGIN',$conn); #开启事务
+ foreach ($sqlArr as $sqltxt) {
+ $sqltxt = trim($sqltxt);
+ if($sqltxt=='') continue;
+ $res = mysql_query($sqltxt,$conn);
+
+ if(mysql_error($conn)){
+ $errnum++; #SQL语句有误
+ $errorTxt .= mysql_error($conn) . "\r\n";
+ }else{
+ if(!$count) continue;
+ #根据SQL语句,增加记录值
+ if(strtoupper(left($sqltxt,6))=="SELECT"){
+ array_push($exesqlCount,mysql_num_rows($res));
+ }else if(strtoupper(left($sqltxt,6))=="INSERT"){
+ array_push($exesqlCount,mysql_insert_id());
+ }else{
+ array_push($exesqlCount,mysql_affected_rows());
+ }
+ }
+ }
+ if($errnum>0){
+ #回滚数据
+ mysql_query("ROLLBACK",$conn);
+ self::error($errorTxt);
+ return false;
+ }else{
+ mysql_query("COMMIT",$conn);
+ return true;
+ }
+ unset($sqlArr,$conn,$res,$errorTxt,$errnum);
+ }
+
+ /*记录集转数组*/
+ public function getrow($rs,$fmttype=1){
+ $conf=array(MYSQL_NUM,MYSQL_ASSOC,MYSQL_BOTH);
+ $res = mysql_fetch_array($rs,$conf[$fmttype]);
+ if(is_array($res))$res = array_change_key_case($res);
+ return $res;
+ unset($res,$conf);
+ }
+
+ /*取sql语句第一行第一列的值*/
+ public function getval($sql){
+ $res = self::getrow(self::exe($sql),0);
+ if(!is_array($res)){
+ return '';
+ }else{
+ return $res[0];
+ }
+ unset($res);
+ }
+
+ /*
+ 取SQL语句结果数组
+ indexkey为结果数组的key用数据库的哪个列
+ */
+ public function getarray($sql,$indexkey=''){
+ $res = array();
+ $sqlres = self::exe($sql);
+ while($row=self::getrow($sqlres)){
+ if($indexkey==''){
+ $res[] = $row;
+ }else{
+ $res[$row[$indexkey]] = $row;
+ }
+ }
+ return $res;
+ unset($res,$sqlres,$row);
+ }
+
+ /*
+ 取SQL语句结果数组的第一条记录
+ */
+ public function getone($sql){
+ $res = self::getarray($sql);
+ if(count($res)==0){
+ return array();
+ }else{
+ return $res[0];
+ }
+ unset($res);
+ }
+
+ /*
+ 处理所有出错信息
+ $errMsg自定义的出错信息
+ */
+ public function error($errMsg=''){
+ if ($errMsg == "") {
+ $m = "mysql error:\r\n ";
+ $m .= mysql_errno() . ":" . mysql_error () . "\r\n ";
+ $m .= 'URL:'.$_SERVER["REQUEST_URI"];
+ echo $m;
+ }else{
+ $m .= "mysql error:\r\n ";
+ $m .= $errMsg . "\r\n ";
+ $m .= 'URL:'.$_SERVER["REQUEST_URI"];
+ echo $m;
+ }
+ $log="=====================================\r\n ";
+ $log .= date("Y-m-d H:i:s")."\r\n ";
+ $log .= $m ."\r\n ";
+ echo $log;
+ //@file_put_contents("game/log/database.log",$log,FILE_APPEND);
+ unset($m);
+ exit();
+ }
+ /*
+ 更新SQL语句
+ $tablename 表名
+ $param 更新数据,字符串或array
+ $where 更新条件
+ 返回SQL语句
+ */
+ public function update($tablename,$param,$where=''){
+ if(!is_array($param)){
+ self::error("UPDATE语句错误:param类型不符");
+ }
+ $paramArr=array();
+ foreach($param as $key => $val){
+ if(is_array($val)){
+ array_push($paramArr,"$key=".$val[0]);
+ }else{
+ array_push($paramArr,"$key='".addslashes($val)."'");
+ }
+ }
+ $param = implode(',',$paramArr);
+ unset($paramArr,$key,$val);
+ return 'UPDATE `'.strtolower(trim($tablename)) .'` SET '. $param . ($where ? ' WHERE ' . $where : '');
+ }
+ /*
+ 插入SQL语句
+ $tablename 表名
+ $param 插入数据array
+ 返回SQL语句
+ */
+ public function insert($tablename,$param){
+ if(!is_array($param)){
+ self::error("INSERT语句错误:param类型不符");
+ }
+ $paramArr=array();
+ foreach($param as $key => $val){
+ array_push($paramArr,"$key='".addslashes($val)."'");
+ }
+ $param = implode(',',$paramArr);
+ unset($paramArr,$key,$val);
+ return 'INSERT INTO `'.strtolower(trim($tablename)) .'` SET '. $param;
+ }
+ /*
+ 删除SQL语句
+ $tablename 表名
+ $where 删除条件
+ 返回SQL语句
+ */
+ public function delete($tablename,$where=''){
+ if (!$where) {
+ self::error("删除函数必须指定条件");
+ return 0;
+ }
+ return 'DELETE FROM `' . $tablename . '` WHERE ' . $where;
+ }
+
+ /*
+ 查询SQL语句
+ $fields 字段
+ $tablename 表名
+ $where 条件
+ $orderby 排序
+ $limit 记录条数
+ 返回SQL语句
+ */
+ public function select($fields,$tablename,$where='',$orderby='',$limit=''){
+ $sql = 'SELECT ' . $fields . ' FROM `' . $tablename .'`' . ($where ? ' WHERE ' . $where : '') . ($orderby ? ' ORDER BY ' . $orderby . ' ':'') . ($limit ? ' limit ' . $limit : '');
+ return $sql;
+ unset($sql);
+ }
+}
+
+##MEMCACHE类
+class CACHE{
+ public static $conns = array();
+
+ #根据配置文件,取连接资源
+ function getconnG(){
+ global $_CONFIG;
+ return self::connCache($_CONFIG['memcache']);
+ }
+
+ #连接到memcache
+ public function connCache($dbconf){
+ $key = $dbconf['ip'] .'.'. $dbconf['port'];
+
+ if(self::$conns[$key]){
+ return self::$conns[$key];
+ }
+
+ $conn = memcache_pconnect($dbconf['ip'], $dbconf['port']); //采用持久连接
+ //$conn = memcache_connect($dbconf['ip'], $dbconf['port']);
+ self::$conns[$key]=$conn;
+ return $conn;
+ }
+
+ #设置缓存内容
+ public function set($key,$val,$timeout=0){
+ return memcache_set(self::getconnG(),$key,$val,0,$timeout);#timeout秒后超时
+ }
+
+ #读取缓存内容
+ public function get($key){
+ return memcache_get(self::getconnG(),$key);
+ }
+
+ #删除指定key缓存
+ public function del($key,$delay=0){
+ return memcache_delete(self::getconnG(),$key,$delay); #delay秒后删除
+ }
+
+ #删除所有缓存
+ public function delall(){
+ memcache_flush(self::getconnG());
+ }
+
+ #关闭连接
+ public function close(){
+ @memcache_close(self::getconnG());
+ }
+}
+
+
+##游戏SESSIOON类
+class SESS{
+ public static $init = 0;
+ public static $preKey = 'CiNiAoSeSs';
+
+ #初始化session
+ public function initSession(){
+ if(self::$init==1) return;
+ global $_CONFIG; #加载配置文件,将session保存到memecahe
+ header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
+ //ini_set("session.save_handler","memcache");
+ //ini_set("session.save_path",$_CONFIG['memcache']['ip'].":".$_CONFIG['memcache']['port']);
+ ini_set('session.gc_maxlifetime',172800);
+ /*可以修改为使用文件方式保存session
+ ini_set("session.save_handler","files");
+ session_save_path( "session/");
+ */
+ session_start();
+ self::$init = 1;
+ }
+
+ #读取session
+ public function get($key){
+ self::initSession();
+ return $_SESSION[self::$preKey.$key];
+ }
+
+ #设置session
+ public function set($key,$val){
+ self::initSession();
+ $_SESSION[self::$preKey.$key] = $val;
+ }
+
+ #删除指定session
+ public function del($key){
+ self::initSession();
+ unset($_SESSION[self::$preKey.$key]);
+ }
+
+ #删除所有session
+ public function delall(){
+ self::initSession();
+ session_destroy();
+ }
+}
+
+?>
diff --git a/inc/config.php b/inc/config.php
new file mode 100644
index 0000000..2be63d4
--- /dev/null
+++ b/inc/config.php
@@ -0,0 +1,9 @@
+array(
+ ),
+ 'mongo' => 'mongodb://root:iamciniao@127.0.0.1:27017/admin'
+);
+
+?>
\ No newline at end of file
diff --git a/inc/filedb.php b/inc/filedb.php
new file mode 100644
index 0000000..b857f4c
--- /dev/null
+++ b/inc/filedb.php
@@ -0,0 +1,141 @@
+";
+
+ $file = self::getFile($uid,$table);
+ //we($file);
+ Core_Fun_File::write($file,$str);
+ global $FILEDBCACHE;
+ unset($FILEDBCACHE[$file]);
+ }
+ /*
+ 获取一个缓存数据
+ */
+ public function get($uid,$table){
+ $file = self::getFile($uid,$table);
+ if(!file_exists($file)) return false;
+ global $FILEDBCACHE;
+ if(!$FILEDBCACHE[$file]){
+ $FILEDBCACHE[$file] = 1;
+ include $file;
+ }
+ return true;
+ }
+}
+?>
\ No newline at end of file
diff --git a/inc/guide.php b/inc/guide.php
new file mode 100644
index 0000000..0994b39
--- /dev/null
+++ b/inc/guide.php
@@ -0,0 +1,120 @@
+boards->findOne(array(
+ 'title' => new MongoRegex("/".$boardTitle."/$i"),
+ 'archived' => false
+ ));
+
+// $res = iterator_to_array($templateBoard);
+// var_dump($templateBoard);
+
+ if($templateBoard){
+ return $templateBoard['_id'];
+ }
+
+ return;
+
+
+
+}
+
+// 添加新员工新手指导看板 标题名字 @<部门名字>@新手指导看板 @开发部@新手指导看板
+function insertGuideBoardForTemplateBoard($uid,$templateBoardId){
+ if(!$templateBoardId){
+ return;
+ }
+
+ global $wekan;
+
+ $_boardId = uniqid();
+// echo 'boardId '.$_boardId;
+
+ $resReturn = array();
+
+ $resReturn['boardId'] = $_boardId;
+
+ $_uid = $_SESSION['leguworkUID'];
+
+ $data = array(
+ "_id" => $_boardId ,
+ "title" => "新手指导" ,
+ "permission" =>"private",
+ "slug" => "board",
+ "archived" => false,
+ "view" => "board-view-lists",
+ "createdAt" => new MongoDate(time()),
+ "stars" => 0 ,
+ "labels" => initLables(),
+ "qalabels" => initQALables(),
+ "members" => array(
+ array(
+ "userId" => $uid,
+ "isAdmin" => true,
+ "isActive" => true,
+ "isCommentOnly" => false
+ )
+ ),
+ "color" => "belize",
+ "modifiedAt" => new MongoDate(time()),
+ "watchers" => array(
+ array(
+ "userId" => $uid ,
+ "level" =>"tracking"
+ )
+ )
+ );
+
+ $res = $wekan->boards->insert( $data );
+
+ // 添加列表
+ $tplLists = $wekan->lists->find(array(
+ 'boardId' => $templateBoardId,
+ 'archived' => false
+ ));
+
+ $tplLists = iterator_to_array($tplLists);
+
+ $listArr = array();
+ foreach($tplLists as $tplListId=>$tplListValue){
+ $_listId = uniqid();
+
+// echo 'listid '.$_listId;
+ $tplListValue['_id'] = $_listId;
+ $tplListValue['boardId'] = $_boardId;
+ $res = $wekan->lists->insert($tplListValue);
+
+ // 该列表下的卡片
+ $tplCards = $wekan->cards->find(array(
+ 'boardId' => $templateBoardId,
+ 'listId'=>$tplListId,
+ 'archived' => false
+ ));
+
+ $tplCards = iterator_to_array($tplCards);
+
+ $cardArr = array();
+ foreach($tplCards as $tplCardId=>$tplCardValue){
+ $_cardId = uniqid();
+// echo 'cardid '.$_cardId;
+ $cardArr[] = $_cardId;
+ $tplCardValue['_id'] = $_cardId;
+ $tplCardValue['boardId'] = $_boardId;
+ $tplCardValue['listId'] = $_listId;
+ $tplCardValue['members'] = array($uid);
+ $res = $wekan->cards->insert($tplCardValue);
+ }
+ $listArr[$_listId] = $cardArr;
+
+
+ }
+ $resReturn['lists'] = $listArr;
+
+ return $resReturn;
+
+
+}
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..6248585
--- /dev/null
+++ b/index.php
@@ -0,0 +1,22 @@
+close();
+?>
diff --git a/labels.html b/labels.html
new file mode 100644
index 0000000..eb839af
--- /dev/null
+++ b/labels.html
@@ -0,0 +1,56 @@
+<%
+var card = DATA.cards[ DATA.lastShowCardID ];
+var board = DATA.boards[ card.boardId ];
+%>
+
+
+
+
+ <%
+ for(var i=0;i
+
+
+ <%=label.name%>
+ <%= (_isSelect?' ':'')%>
+
+
+
+
+ <% } %>
+
+
+ 增加标签
+
+
+
+
+
+
+
+
+
+ <%
+ var colors = ['legugreen','legupurple','legublue','leguyellow','legured','legupink','legugray','leguaqua'];
+ for(var i=0;i
+
+
+
+
+ <% } %>
+
+
确定
+
删除
+
+
+
\ No newline at end of file
diff --git a/leftbar.html b/leftbar.html
new file mode 100644
index 0000000..eba6ef1
--- /dev/null
+++ b/leftbar.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/list.php b/list.php
new file mode 100644
index 0000000..01f3ea9
--- /dev/null
+++ b/list.php
@@ -0,0 +1,555 @@
+
+require_once "api.php";
+$boardid = r('boardid');
+
+$boards = boards(true);
+$lists = getlists($boardid);
+$cards = getcards($boardid,array_keys($lists));
+$users = getusers();
+$risklabels = getRiskLabels();
+$allrisklabels = getAllRiskLabels();
+$yanqidepartmentuser = getYanQiDepartmentUser();
+
+$DATA = array(
+ 'boardid' => $boardid,
+ 'boards' => $boards,
+ 'lists' => $lists,
+ 'cards' => $cards,
+ 'users'=>$users,
+ 'risklabels'=>$risklabels,
+ 'allrisklabels'=>$allrisklabels,
+ 'yanqidepartmentuser'=> $yanqidepartmentuser,
+ 'ts'=>time(),
+);
+?>
+
+
+
+
+ require_once "header.html"; ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ require_once "leftbar.html"; ?>
+ require_once "projectheader.html"; ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/listmenu.html b/listmenu.html
new file mode 100644
index 0000000..304e991
--- /dev/null
+++ b/listmenu.html
@@ -0,0 +1,86 @@
+
\ No newline at end of file
diff --git a/memberlist.html b/memberlist.html
new file mode 100644
index 0000000..09a5a75
--- /dev/null
+++ b/memberlist.html
@@ -0,0 +1,50 @@
+<%
+var currCard = DATA.cards[ DATA.lastShowCardID ];
+var lastTs = DATA.ts-86400*7;
+%>
+
+
+
+
+
+
+
+
+ <%
+ var order = getMemberOrder();
+ for(var uid in data){
+ data[uid]['_clientOrder'] = order[uid] || 0;
+ }
+ var values = [];
+ for(var uid in data){
+ if(data[uid]['lastlogin'] > lastTs){
+ values.push( data[uid] );
+ }
+ }
+
+ values.sort(function(a,b){
+ return b._clientOrder - a._clientOrder;
+ });
+
+ for(var _i=0;_i< values.length;_i++){
+ var uid = values[_i]._id;
+ var _isSelect = "";
+ if(currCard.members.indexOf(uid) != -1){
+ _isSelect = true;
+ }
+ %>
+
+
+ <%=data[uid].profile.fullname%>@<%=data[uid].orgname%>(<%=data[uid].username%>)
+ <%= (_isSelect?' ':'')%>
+
+
+ <% } %>
+
+
+
+
\ No newline at end of file
diff --git a/mycalendar.php b/mycalendar.php
new file mode 100644
index 0000000..a092fe8
--- /dev/null
+++ b/mycalendar.php
@@ -0,0 +1,134 @@
+
+/*
+require_once "api.php";
+$boardid = r('boardid');
+
+$boards = getboards();
+$cards = getmycards();
+//we($mycards);
+//$lists = getlists($boardid);
+//$cards = getcards($boardid,array_keys($lists));
+$users = getusers();
+
+$list = array();
+foreach($cards as $cid=>$card){
+ $borderid = $card['boardId'];
+ if($list[$borderid])continue;
+ if(!$boards[ $borderid ]['title'])continue;
+ $list[ $borderid ] = array(
+ "archived"=>false,
+ "title"=> $boards[ $borderid ]['title'],
+ "_id"=> $borderid
+ );
+}
+
+$DATA = array(
+ 'boardid' => $boardid,
+ 'boards' => $boards,
+ 'lists' => $list,
+ 'cards' => $cards,
+ 'users'=>$users
+);
+*/
+?>
+
+
+
+
+ require_once "header.html"; ?>
+
+
+
+
+
+ require_once "leftbar.html"; ?>
+ require_once "projectheader.html"; ?>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mylists.php b/mylists.php
new file mode 100644
index 0000000..f9c9141
--- /dev/null
+++ b/mylists.php
@@ -0,0 +1,366 @@
+
+require_once "api.php";
+$boardid = r('boardid');
+
+$boards = getboards();
+$cards = getmycards();
+//we($mycards);
+//$lists = getlists($boardid);
+//$cards = getcards($boardid,array_keys($lists));
+$users = getusers();
+$risklabels = getRiskLabels();
+$allrisklabels = getAllRiskLabels();
+
+$list = array();
+foreach($cards as $cid=>$card){
+ $borderid = $card['boardId'];
+ if($list[$borderid])continue;
+ if(!$boards[ $borderid ]['title'])continue;
+ $list[ $borderid ] = array(
+ "archived"=>false,
+ "title"=> $boards[ $borderid ]['title'],
+ "_id"=> $borderid
+ );
+}
+
+/*
+$DATA = array(
+ 'boardid' => $boardid,
+ 'boards' => $boards,
+ 'lists' => array("mime"=>array(
+ "archived"=>false,
+ "title"=>"与我相关",
+ "_id"=>'mime'
+ )),
+ 'cards' => $cards,
+ 'users'=>$users
+);
+*/
+
+$DATA = array(
+ 'boardid' => $boardid,
+ 'boards' => $boards,
+ 'lists' => $list,
+ 'cards' => $cards,
+ 'users'=>$users,
+ 'risklabels'=>$risklabels,
+ 'allrisklabels'=>$allrisklabels,
+ 'ts'=>time(),
+);
+
+?>
+
+
+
+
+ require_once "header.html"; ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ require_once "leftbar.html"; ?>
+ require_once "projectheader.html"; ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projectheader.html b/projectheader.html
new file mode 100644
index 0000000..27bcc42
--- /dev/null
+++ b/projectheader.html
@@ -0,0 +1,194 @@
+
+
\ No newline at end of file
diff --git a/proreport.html b/proreport.html
new file mode 100644
index 0000000..0e796ae
--- /dev/null
+++ b/proreport.html
@@ -0,0 +1,30 @@
+
+
diff --git a/python/tw.py b/python/tw.py
new file mode 100644
index 0000000..f62aa42
--- /dev/null
+++ b/python/tw.py
@@ -0,0 +1,32 @@
+#!/usr/bin/python
+#coding:utf-8
+'''
+twisted 公共类
+@author
+@email4041990@qq.com
+'''
+
+import os
+if os.name=='nt':
+ try:
+ import twisted.internet.iocpreactor as iocpreactor
+ iocpreactor.install()
+ except:
+ print "iocp error"
+ pass
+else:
+ try:
+ import twisted.internet.epollreactor as epollreactor
+ epollreactor.install()
+ except:
+ print "epoll error"
+
+from twisted.internet.protocol import Factory,Protocol
+from twisted.internet import reactor,threads,defer
+from twisted.internet.protocol import ClientFactory
+
+if os.name=='nt':
+ #开发机只开1个线程 以便发现阻塞点
+ reactor.suggestThreadPoolSize(1)
+else:
+ reactor.suggestThreadPoolSize(100)
\ No newline at end of file
diff --git a/python/tw.pyc b/python/tw.pyc
new file mode 100644
index 0000000..a548560
Binary files /dev/null and b/python/tw.pyc differ
diff --git a/python/websocket.py b/python/websocket.py
new file mode 100644
index 0000000..2a2f720
--- /dev/null
+++ b/python/websocket.py
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+#coding:utf-8
+
+import sys,os,socket
+import tw,ws
+
+client = []
+
+class Server(tw.Protocol):
+ #有客户端接入
+ def connectionMade(self):
+ self.attr={} #主要保存客户端的连接类型
+ self.socketLeftString = '' #socket传输中需要粘包的数据
+ self.transport.getHandle().setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF,32*1024)
+ client.append( self )
+
+ #有客户端断开
+ def connectionLost(self,reason):
+ if self in client:
+ client.remove(self)
+
+ print 'connectionLost'
+
+ #收到客户端发来数据
+ def dataReceived(self, msg):
+ #WS握手
+ if msg.lower().find('upgrade: websocket') != -1:
+ ws.shake(self,msg)
+ return
+ ws.parse_recv_data(self,msg,self._dataReceived)
+
+ #数据解压后,执行解包粘包操作
+ def _dataReceived (self,msg):
+ if msg=='ping':
+ self.send('pong')
+
+ elif msg.startswith('sendOther@_@'):
+ msg = msg.replace('sendOther@_@','')
+
+ for c in client:
+ if c == self:
+ continue
+ c.send( msg )
+
+
+ def send (self,msg,callback=None):
+ msg = str(msg)
+ msg = ws.send_data(self,msg)
+ return self.sendDo(msg,callback)
+
+ def sendDo(self,msg,callback=None):
+ if not self.transport.connected or msg is None:
+ return
+ msg = str(msg)
+ tw.reactor.callFromThread(self.transport.write,msg)
+
+#启动服务器
+if __name__=='__main__':
+ f = tw.Factory()
+ f.protocol = Server
+ tw.reactor.listenTCP(3000,f)
+ print 'starting 3000'
+ tw.reactor.run()
diff --git a/python/ws.py b/python/ws.py
new file mode 100644
index 0000000..9a02b75
--- /dev/null
+++ b/python/ws.py
@@ -0,0 +1,161 @@
+#!/usr/bin/python
+#coding:utf-8
+
+#本文件主要用于webSocket握手协议及消息处理
+import hashlib, struct, base64
+
+#WS握手开始,socket=socket对象 msg=消息体
+def shake (conn,msg):
+ headers = {}
+ header, data = msg.split('\r\n\r\n', 1)
+ for line in header.split('\r\n')[1:]:
+ key, value = line.split(": ", 1)
+ headers[key] = value
+ if "Host" in headers:headers["Location"] = "ws://%s/" % headers["Host"]
+ conn.attr['type'] = 'ws'
+
+ #老版本的ws协议 目主要用于兼容IOS
+ if headers.has_key('Sec-WebSocket-Key1'):
+ key1 = headers["Sec-WebSocket-Key1"]
+ key2 = headers["Sec-WebSocket-Key2"]
+ key3 = data[:8]
+ token = creatToken(key1, key2, key3)
+ handshake = '\
+HTTP/1.1 101 Web Socket Protocol Handshake\r\n\
+Upgrade: WebSocket\r\n\
+Connection: Upgrade\r\n\
+Sec-WebSocket-Origin: %s\r\n\
+Sec-WebSocket-Location: %s\r\n\r\n\
+' %(headers['Origin'], headers['Location'])
+
+ conn.attr['newVersion'] = False
+ conn.sendDo(handshake + token)
+ #新版本ws协议
+ else:
+ key = headers['Sec-WebSocket-Key']
+ token = creatToken2(key)
+ handshake = '\
+HTTP/1.1 101 Switching Protocols\r\n\
+Upgrade: WebSocket\r\n\
+Connection: Upgrade\r\n\
+Sec-WebSocket-Accept: %s\r\n\r\n\
+' % (token)
+ conn.attr['newVersion'] = True
+ conn.sendDo(handshake)
+
+#格式化http协议发来的消息
+def parse_httprecv_data(conn,_string,callBack):
+ #TODO解密_string
+ raw_str = _string
+ callBack(raw_str)
+
+#WS收到消息时,格式化消息
+def parse_recv_data(conn,_string,callBack):
+
+ if not 'socket_BUFF' in conn.attr:
+ conn.attr['socket_BUFF'] = ''
+
+ msg = conn.attr['socket_BUFF'] + _string
+
+ if 'newVersion' in conn.attr and conn.attr['newVersion']:
+ code_length = ord(msg[1]) & 127
+ if code_length == 126:
+ msgLen = struct.unpack('>H',msg[2:4])[0]
+ masks = msg[4:8]
+ msgTo = 8+msgLen
+ data = msg[8:msgTo]
+ elif code_length == 127:
+ msgLen = struct.unpack('>I',msg[2:6])[0]
+ masks = msg[10:14]
+ msgTo = 14+msgLen
+ data = msg[14:msgTo]
+ else:
+ msgLen = code_length
+ masks = msg[2:6]
+ msgTo = 6+msgLen
+ data = msg[6:msgTo]
+
+ #数据长度不够,等待
+ if len(data)> 8))
+ back_str.append(chr(data_length & 0xFF))
+
+ back_str = "".join(back_str) + raw_str
+ '''
+ else:
+ back_str = '\x00%s\xFF' % (raw_str)
+ return back_str
+
+#老版本WS服务器握手信息
+def creatToken( key1, key2, key3):
+ num1 = int("".join([digit for digit in list(key1) if digit.isdigit()]))
+ spaces1 = len([char for char in list(key1) if char == " "])
+ num2 = int("".join([digit for digit in list(key2) if digit.isdigit()]))
+ spaces2 = len([char for char in list(key2) if char == " "])
+
+ combined = struct.pack(">II", num1/spaces1, num2/spaces2) + key3
+ return hashlib.md5(combined).digest()
+
+#新版本WS服务器握手信息
+def creatToken2(key):
+ key = key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
+ ser_key = hashlib.sha1(key).digest()
+ return base64.b64encode(ser_key)
+
+if __name__=='__main__':
+ print send_data("conn", "raw_str"*50000)
\ No newline at end of file
diff --git a/python/ws.pyc b/python/ws.pyc
new file mode 100644
index 0000000..f6430b3
Binary files /dev/null and b/python/ws.pyc differ
diff --git a/qalabels.html b/qalabels.html
new file mode 100644
index 0000000..c3e05cc
--- /dev/null
+++ b/qalabels.html
@@ -0,0 +1,59 @@
+<%
+var card = DATA.cards[ DATA.lastShowCardID ];
+var board = DATA.boards[ card.boardId ];
+if(!board.qalabels){
+ board.qalabels = [];
+}
+%>
+
+
+
+
+ <%
+ for(var i=0;i
+
+
+ <%=label.name%>
+ <%= (_isSelect?' ':'')%>
+
+
+
+
+ <% } %>
+
+
+ 增加标签
+
+
+
+
+
+
+
+
+
+ <%
+ var colors = ['legugreen','legupurple','legublue','leguyellow','legured','legupink','legugray','leguaqua'];
+ for(var i=0;i
+
+
+
+
+ <% } %>
+
+
确定
+
删除
+
+
+
\ No newline at end of file
diff --git a/risklabels.html b/risklabels.html
new file mode 100644
index 0000000..31ae576
--- /dev/null
+++ b/risklabels.html
@@ -0,0 +1,56 @@
+<%
+var card = DATA.cards[ DATA.lastShowCardID ];
+var board = DATA.boards[ card.boardId ];
+%>
+
+
+
+
+
+ <%
+ for(var i in data){
+ var label = data[i];
+
+ var _isSelect = false;
+ if(card.risklabelIds && card.risklabelIds.indexOf(label._id) != -1){
+ _isSelect = true;
+ }
+ %>
+
+
+ <%=label.name%>
+ <%= (_isSelect?' ':'')%>
+
+
+
+
+ <% } %>
+
+
+
+
+
+
+
+
+
+
+ <%
+ var colors = ['legugreen','legupurple','legublue','leguyellow','legured','legupink','legugray','leguaqua'];
+ for(var i=0;i
+
+
+
+
+ <% } %>
+
+
确定
+
删除
+
+
+
diff --git a/scripts/Find Results b/scripts/Find Results
new file mode 100644
index 0000000..c36a9ea
--- /dev/null
+++ b/scripts/Find Results
@@ -0,0 +1,46 @@
+Searching 773 files for "showIssueTags"
+
+/Users/SriLanka/php/leguwork_draft_new/scripts/cardinfo.js:
+ 333 // DATA.allrisklabels[k] = json[k];
+ 334 // }
+ 335: // showIssueTags();
+ 336 // });
+ 337 // }
+
+1 match in 1 file
+
+
+Searching 773 files for "fmtAllRiskLabelsByCardID"
+
+/Users/SriLanka/php/leguwork_draft_new/scripts/cardinfo.js:
+ 48
+ 49 fmtCommentsByCardID(cardid);
+ 50: fmtAllRiskLabelsByCardID(cardid);
+ 51 fmtCheckListByCardID(cardid);
+ 52 showAttachmentsByCardID(cardid);
+ ..
+ 326 }
+ 327
+ 328: // function fmtAllRiskLabelsByCardID(cardid){
+ 329 // $.get('./?app=api&apiact=get_allrisktags&cardid='+cardid,function(text){
+ 330 // var json = JSON.parse( text );
+
+2 matches in 1 file
+
+
+Searching 773 files for "fmtAllRiskLabelsByCardID"
+
+/Users/SriLanka/php/leguwork_draft_new/scripts/cardinfo.js:
+ 48
+ 49 fmtCommentsByCardID(cardid);
+ 50: // fmtAllRiskLabelsByCardID(cardid);
+ 51 fmtCheckListByCardID(cardid);
+ 52 showAttachmentsByCardID(cardid);
+ ..
+ 326 }
+ 327
+ 328: // function fmtAllRiskLabelsByCardID(cardid){
+ 329 // $.get('./?app=api&apiact=get_allrisktags&cardid='+cardid,function(text){
+ 330 // var json = JSON.parse( text );
+
+2 matches in 1 file
diff --git a/scripts/cardPopover.js b/scripts/cardPopover.js
new file mode 100644
index 0000000..8285da2
--- /dev/null
+++ b/scripts/cardPopover.js
@@ -0,0 +1,44 @@
+function showCardPopover(){
+ var html = T( $('#tmpl-cardpopover').html() );
+ $('body').append( html );
+ $('#cardPopoverMask').fadeIn(100).css('width',$(document).width());
+
+ $('.card-details-title').text('项目集成');
+
+ // $.get('?app=api&apiact=finishcount&boardid='+DATA.boardid,function(txt){
+ $.get('./?app=api&apiact=getsettingcardinfo&boardid=' + DATA.boardid + '&cardtitle='+ 'hearderleft',function(text){
+
+ console.log(text);
+ var j = JSON.parse(text);
+ console.log(j);
+
+ var cardid = Object.keys(j)[0];
+ cardData = j[cardid];
+ console.log(cardData);
+
+ if (cardData){
+ html = cardData['description'];
+
+ } else {
+ html = "添加标题为__setting.hearderleft 的卡片 "
+ }
+
+ $('#cardpopoverdata').append(html);
+
+ })
+}
+function closeCardPopover(){
+ $('#cardPopoverMask').remove();
+ $('#cardPopover').remove();
+}
+
+
+$(function(){
+ $('body').on("click","#cardPopoverMask",function(){
+ closeCardPopover();
+ });
+ $('body').on("click","#cardPopoverClose",function(){
+ closeCardPopover();
+ });
+});
+
diff --git a/scripts/card_list_timeline.js b/scripts/card_list_timeline.js
new file mode 100644
index 0000000..e716db6
--- /dev/null
+++ b/scripts/card_list_timeline.js
@@ -0,0 +1,218 @@
+function showCardTimeline(listid){
+
+ // console.log('==========');
+ // console.log(listid);
+
+ var html = T( $('#tmpl-card_timeline').html() );
+ $('body').append( html );
+ $('#cardListTimelineMask').fadeIn(100).css('width',$(document).width());
+
+ // $('.card-details-title').text('项目集成');
+
+ // $.get('?app=api&apiact=finishcount&boardid='+DATA.boardid,function(txt){
+ $.get('./?app=api&apiact=getsettingcardinfo&boardid=' + DATA.boardid + '&cardtitle='+ 'hearderleft',function(text){
+
+ // console.log(text);
+ var j = JSON.parse(text);
+ // console.log(j);
+
+ var cardid = Object.keys(j)[0];
+ cardData = j[cardid];
+ // console.log(cardData);
+
+ if (cardData){
+ html = cardData['description'];
+
+ } else {
+ html = "添加标题为__setting.hearderleft 的卡片 "
+ }
+ html += listid;
+ // $('#cardListTimelineData').append(html);
+
+
+ var calendarEl = document.getElementById('cardListTimelineData');
+
+
+
+ var calendar = new FullCalendar.Calendar(calendarEl, {
+ plugins: ['interaction', 'resourceTimeline'],
+ schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
+ timeZone: '+8',
+ locale: 'zh-cn',
+ defaultView: 'resourceTimelineMonth',
+ aspectRatio: 2.4,
+ header: {
+ left: 'prev,next',
+ // center: 'title',
+ center: 'title',
+ right: 'resourceTimelineDay,resourceTimelineWeek,resourceTimelineMonth'
+ },
+
+
+ editable: false,
+ resourceLabelText: '单子',
+ // resourceGroupField: 'group',
+ resourceAreaWidth: "300px",
+
+ resources: './?app=api&apiact=get_timeline_list_card&list=' + listid,
+
+ // resources11: [
+ // {"id":"5cd52386c5363","title":"fasd
"},{"id":"3qCRNfNDywDcvfhxJ","group":"\u7f8e\u672f1\u90e8","title":"\u9648\u9752"},{"id":"5aeab9d8e8ab3","group":"\u6d4b\u8bd5\u90e8","title":"\u5218\u601d\u79cb"},{"id":"5aebf6e46df68","group":"H5\u5ba2\u6237\u7aef","title":"\u675c\u6052\u665f"},{"id":"5aeff82ec323d","group":"\u670d\u52a1\u7aef","title":"\u5f90\u671d"},{"id":"5b42d28a3df35","group":"UI\u7ec4","title":"\u738b\u4f73\u4f1f"},
+ // ],
+
+ resourceRender: function(renderInfo) {
+ // console.log("==-==-=");
+ // console.log(renderInfo);
+
+ var labels = renderInfo.resource.extendedProps.labels;
+ var board = DATA.boards[ DATA.boardid];
+ // console.log(labels);
+
+ // console.log(board.labels);
+
+ var html = ``;
+
+
+ labels.forEach(function (ele) {
+ var label = getLabelsData(ele,board.labels);
+ html += ` ${label.name} `;
+
+ });
+
+ if(renderInfo.resource.extendedProps.isyanqi){
+ html += ` 延期 `;
+ }
+
+ html += `
`;
+
+ // $(info.el).data('id',info.event.extendedProps.id);
+ $(renderInfo.el).children('div').append(html);
+ },
+
+
+ events: './?app=api&apiact=get_timeline_list_card_events&list=' + listid,
+
+ // events11: [
+ // {allDay: true,
+ // boardid: "5bbdbf66031d2",
+ // end: "2019-05-11",
+ // resourceId: "5cd52386c5363",
+ // start: "2019-05-09",
+ // title: "地牢冒险",
+ // isyanqi: "延期了",
+ // url: "./?app=list&boardid=5bbdbf66031d2#cardid=5c63af7623239"}
+ // ],
+
+ eventRender: function(info) {
+
+ // console.log("==-==-=");
+ // console.log(info);
+
+ $(info.el).data('id',info.event.extendedProps.cardid);
+ $(info.el).addClass('card-list-timeline-event-open');
+
+ if (info.event.extendedProps.isyanqi){
+ var txt = rtime2txt(yqrt);
+ if (txt){
+ var yqtxt = `延期${txt} `;
+ }
+ // var yqtxt = `延期${info.event.extendedProps.yanqiday}天 ${info.event.extendedProps.yanqiRt} `;
+
+ $(info.el).prepend(yqtxt);
+ }
+
+ // var tooltip = new Tooltip(info.el, {
+ // title: info.event.extendedProps.description,
+ // placement: 'top',
+ // trigger: 'hover',
+ // container: 'body'
+ // });
+ }
+
+ // events: function(info,success,failure){
+ // console.log('==========');
+ // console.log(info);
+ // success(function () {
+ // return [
+ // {allDay: true,
+ // boardid: "5bbdbf66031d2",
+ // end: "2019-05-11",
+ // resourceId: "5cd52386c5363",
+ // start: "2019-05-09",
+ // title: "地牢冒险",
+ // url: "./?app=list&boardid=5bbdbf66031d2#cardid=5c63af7623239"}
+ // ]
+ // });
+ //
+ // },
+
+ });
+
+ calendar.render();
+
+ // setTimeout(function () {
+ // $('.fc-expander').click();
+ // }, 100);
+
+
+ })
+}
+
+function closeCardListTimeline(){
+ $('#cardListTimelineMask').remove();
+ $('#cardListTimeline').remove();
+}
+
+function getLabelsData(labelsId,labels){
+ var res = '';
+ labels.forEach(function (ele) {
+ if (ele._id == labelsId){
+ res = ele
+ }
+
+ });
+ return res
+
+}
+
+// 时间转字符串 天 小时 分钟
+function rtime2txt(rt) {
+ var txt = '';
+ // 天
+ if (rt > 24*3600){
+ txt = parseInt(rt/(24*3600)) + '天';
+ // 小时
+ }else if (rt > 3600){
+ txt = parseInt(rt/3600) + '小时'
+ // 分钟
+ }else if(rt > 60){
+ txt = parseInt(rt/60) + '分钟'
+ }else {
+ txt = rt + '秒'
+ }
+
+ return txt
+}
+
+
+$(function(){
+ $('body').on("click","#cardListTimelineMask",function(){
+ closeCardListTimeline();
+ });
+ $('body').on("click","#cardTimelineClose",function(){
+ closeCardListTimeline();
+ });
+ $('body').on('click','.card-list-timeline-event-open',function () {
+ showCard( $(this).data('id') );
+ // closeCardListTimeline();
+ });
+
+ $('body').on('click','#cardListTimeline',function () {
+ closeCardInfo();
+ })
+
+
+});
+
+
+
diff --git a/scripts/cardinfo.js b/scripts/cardinfo.js
new file mode 100644
index 0000000..7176d50
--- /dev/null
+++ b/scripts/cardinfo.js
@@ -0,0 +1,1306 @@
+var DC = {};
+DC.unfinishedTitle = '【该单子未创建完成】';
+DC.permission = {};
+
+
+//查看详情
+function closeCardInfo(){
+ $('.isselect').removeClass('isselect');
+ $('#cardinfoMask').remove();
+ $('#cardinfo').remove();
+ $('#memberlist').remove();
+ $('#addlabels').remove();
+ $('#addQAlabels').remove();
+ $('#addRisklabels').remove();
+ DATA.lastShowCardID = null;
+}
+var showCommentsType;
+function showCard(cardid,callback){
+ showCommentsType='default';
+ $.get('./?app=api&apiact=getcardinfo&cardid='+cardid,function(text){
+ var json = JSON.parse(text);
+ location.hash = "cardid="+cardid;
+
+ if( json[cardid] ){
+ DATA.cards[ cardid ] = json[cardid];
+ closeCardInfo();
+
+ DATA.lastShowCardID = cardid;
+ console.log('json',json);
+ $('#card_'+cardid).addClass('isselect');
+
+ var html = T( $('#tmpl-cardinfo').html() , DATA.cards[ cardid ] );
+ $('body').append( html );
+ $('#cardinfoMask').fadeIn(100).css('width',$(document).width());
+
+ _fmtCardInfoLabelsByCardID();
+
+ _fmtCardInfoQALabelsByCardID();
+ _fmtCardInfoRiskLabelsByCardID();
+ _fmtCardInfoIssueTagsByCardID();
+
+ _fmtCardInfoMembersByCardID();
+ // 延期成员
+ //_fmtCardInfoYanQiMembersByCardID();
+
+ setDescription( json[cardid] );
+ setCardInfoTitle( json[cardid] );
+
+ fmtCommentsByCardID(cardid);
+ fmtCheckListByCardID(cardid);
+ showAttachmentsByCardID(cardid);
+
+
+ $('.cardinfo_addcommets_editor,.cardinfo_description_editor').pasteImageReader(function(results){
+ var me = this;
+ $.post('base64upload/index.php',{
+ "data":results.dataURL
+ },function(url){
+ var ov = $(me).val();
+ $(me).val( ov +"" );
+ console.log('url',url,$(me).val());
+ });
+ });
+
+ var names = [];
+ for(var uid in DATA.users){
+ names.push( {'name':DATA.users[uid].username,'fullname': DATA.users[uid].profile.fullname } );
+ }
+
+ //@功能
+ $('.atwho-container').remove();
+ $('.cardinfo_addcommets_editor,.cardinfo_description_editor').atwho({
+ at: "@",
+ data:names,
+ insertTpl: '@${fullname}',
+ displayTpl: "${name} ${fullname} ",
+ limit: 200
+ });
+
+ if(MYID != DATA.cards[DATA.lastShowCardID].userId){
+ $('#cardinfoDelete').hide();
+ }
+ }
+
+ callback && callback(json);
+ });
+}
+
+// 成员
+function _fmtCardInfoMembersByCardID(){
+ fmtMembersByCardID( DATA.lastShowCardID ,function(html){
+ html = ' ' + html;
+ $('#cardinfoMembers').html( html );
+
+ $('#cardinfoMembers .js-member').attr('title','双击去除该用户').unbind().on('dblclick',function(){
+ var uid = $(this).data('id');
+ doSubmitSetMember(DATA.boardid,DATA.lastShowCardID,uid,function () {
+ // 记录日志
+ var uinfo = getUserInfo( uid );
+ var myinfo = getUserInfo( MYID );
+
+ var uNmae = uinfo?uinfo.profile.fullname:data.userId;
+ var commontText = `${myinfo.profile.fullname}[删除] 成员 [${uNmae}]`;
+ doSubmitCommonts(commontText,DATA.boardid,DATA.lastShowCardID);
+
+ });
+ });
+ });
+}
+
+// 延期成员
+function _fmtCardInfoYanQiMembersByCardID(){
+ $('#yanqimembers-h3').hide();
+ $('#yanqimembers-div').hide();
+ checkPermission('removeYanQi',function (isok) {
+ if(isok){
+ $('#yanqimembers-h3').show();
+ $('#yanqimembers-div').show();
+ fmtYanQiMembersByCardID( DATA.lastShowCardID ,function(html){
+ // html = ' ' + html;
+ $('#cardinfoYanQiMembers').html( html );
+
+ $('#cardinfoYanQiMembers .js-member').attr('title','双击去除该用户').unbind().on('dblclick',function(){
+ var uid = $(this).data('id');
+ $(this).remove();
+ doSubmitRemoveYanQiMember(DATA.boardid,DATA.lastShowCardID,uid);
+ });
+ });
+ }else {
+
+ }
+
+ });
+
+
+}
+
+// 标签
+function _fmtCardInfoLabelsByCardID(){
+ fmtLabelsByCardID( DATA.lastShowCardID ,function(html){
+ html = ' ' + html;
+ $('#cardinfoLabels').html( html );
+
+ $('#cardinfoLabels .minicard-label').attr('title','双击去除该标签').unbind().on('dblclick',function(){
+
+ if(! $(this).data("labelName") ) {
+ $(this).data("labelName" ,$(this).text());
+ }
+
+ var labelid = $(this).data('id');
+ var labelName =$(this).data("labelName");
+ var _that = this;
+
+ doSubmitSetLabel(DATA.lastShowCardID,labelid);
+
+ /*
+ var dept = new Set(DATA.riskdept.join(",").split(","))
+ if (dept.has(labelName) == 1){
+
+ if($(_that).data("timeout")){
+ console.log('锁定中...');
+ return;
+ }
+
+
+ var clicks = $(this).data('clicks');
+ if(clicks==null)clicks=0;
+ $(this).data('clicks', clicks*1+1);
+
+ if($(_that).data('clicks')*1==1){
+ $(".fengxianbiaoqian").html("请阅读风险提示,5 秒后再次双击部门标签去标");
+
+ var _times = 5;
+ $(_that).data("timeout",setInterval(function(){
+ $('#clicktimeout').html( --_times);
+
+ if(_times<=0){
+ clearInterval($(_that).data("timeout"));
+ $(_that).data("timeout",null);
+ }
+ },1000))
+
+ }
+
+ window.location.hash = "#fengxianbiaoqian_title";
+ var hash = window.location.hash;
+
+ $('#cardinfoRiskLabels').parent().css('background-color', '#fffdc9').css('padding', '10px').animate({
+ backgroundColor: '#00A087'
+ }, 200);
+ }
+
+
+
+ var isOk = checkMeiShuLabelRemove(labelName);
+ if (isOk){
+ console.log('isok');
+ if( !dept.has(labelName) || (dept.has(labelName) == 1 && $(this).data('clicks')*1 >= 2) ){
+ doSubmitSetLabel(DATA.lastShowCardID,labelid);
+ }
+ }
+ */
+ });
+ });
+}
+
+// 风险标签
+function _fmtCardInfoRiskLabelsByCardID(){
+ return;
+ fmtRiskLabelsByCardID( DATA.lastShowCardID ,function(html){
+ html = ' ' + html;
+ $('#cardinfoRiskLabels').html( html );
+
+ $('#cardinfoRiskLabels .minicard-label').attr('title','双击去除该标签').unbind().on('dblclick',function(){
+ var labelid = $(this).data('id');
+ var labelName = $(this).text();
+
+
+ doSubmitSetRiskLabel(DATA.lastShowCardID,labelid);
+ });
+
+ //_fmtCardInfoIssueTagsByCardID();
+ });
+}
+
+// 风险标签相关事件列表
+function _fmtCardInfoIssueTagsByCardID(){
+ return;
+ fmtIssueTagsByCardID( DATA.lastShowCardID)
+}
+
+// legulabel 中有 美 UI 的去掉 ui验 美验 判断评论图片
+// true 可以执行
+function checkMeiShuLabelRemove(labelName) {
+ var userLabel = ['UI','美'];
+ var checkList = ['美验', '美术验', 'UI验'];
+ var imgStr = '.png';
+ // 排除描述在评论中
+ var commentDesc = '添加了描述';
+ // 判断要去掉的标签
+ if (checkList.indexOf(labelName) != -1){
+
+ // 各自部门去掉各自部门的验需要评论图片
+
+ var userLeguLabelList = MYINFO.legulabel;
+ var isUser = false;
+ var labelnotYan = labelName.replace('验', '');
+ for (var i of userLeguLabelList){
+ // if (userLabel.indexOf(i)!=-1){
+ if (labelnotYan == i){
+ isUser = true;
+ break
+ }
+ }
+ // 用户是美术相关人员
+ if(isUser){
+ // 评论中有图片
+ // 
+ var isComment = false;
+ var nt = parseInt(new Date().getTime()/1000);
+
+ for(let i in DATA.card_comments){
+ let comment = DATA.card_comments[i];
+ if (comment.boardId == DATA.boardid &&
+ comment.cardId == DATA.lastShowCardID &&
+ comment.userId == MYID &&
+ comment.text.indexOf(imgStr) != -1 &&
+ comment.text.indexOf(commentDesc) == -1 &&
+ (nt - comment.createdAt.sec) < 30*60
+ ){
+ isComment = true;
+ }
+ }
+ if (!isComment){
+ alert('在评论区添加游戏内验收的效果图 30分钟以内');
+ return false;
+ }
+ return true;
+
+ }
+ }
+ return true;
+
+
+
+
+
+
+
+}
+
+
+// QA标签
+function _fmtCardInfoQALabelsByCardID(){
+
+ $('#qalabels-h3').hide();
+ $('#qalabels-div').hide();
+ var pms = 'QAlabels';
+ console.log(window.MYINFO);
+
+
+ // 权限判断 __setting.Permission.QAlabels
+ if(window.MYINFO && window.MYINFO.legulabel && window.MYINFO._id){
+ var uid = window.MYINFO._id;
+
+ $('#qalabels-h3').show();
+ $('#qalabels-div').show();
+
+ fmtQALabelsByCardID( DATA.lastShowCardID ,function(html){
+ html = ' ' + html;
+ $('#cardinfoQALabels').html( html );
+
+ $('#cardinfoQALabels .minicard-label').attr('title','双击去除该标签').unbind().on('dblclick',function(){
+ var labelid = $(this).data('id');
+ doSubmitSetQALabel(DATA.lastShowCardID,labelid);
+ });
+ });
+
+
+ // $.get('./?app=api&apiact=getWorkPermission&uid=' + uid + '&pms=' + pms,function (txt) {
+ // var isAllow = JSON.parse(txt);
+ // if (isAllow){
+ // $('#qalabels-h3').show();
+ // $('#qalabels-div').show();
+ //
+ // fmtQALabelsByCardID( DATA.lastShowCardID ,function(html){
+ // html = ' ' + html;
+ // $('#cardinfoQALabels').html( html );
+ //
+ // $('#cardinfoQALabels .minicard-label').attr('title','双击去除该标签').unbind().on('dblclick',function(){
+ // var labelid = $(this).data('id');
+ // doSubmitSetQALabel(DATA.lastShowCardID,labelid);
+ // });
+ // });
+ //
+ // }
+ // });
+
+
+
+ }
+}
+
+
+function showAttachmentsByCardID(cardid){
+ if(cardid!=DATA.lastShowCardID)return;
+ if(!DATA.cards[ DATA.lastShowCardID ])return;
+
+ var attachments = DATA.cards[ DATA.lastShowCardID ].attachments || [];
+ var html = [];
+ for(var i=0;i '+ attachments[i].name +' ');
+ }
+ $('.fujianlist').html( html.join(''));
+}
+
+
+function fmtCommentsByCardID(cardid){
+ $.get('./?app=api&apiact=card_comments&cardid='+cardid,function(text){
+ var json = JSON.parse( text );
+ DATA.card_comments = DATA.card_comments || {};
+ for(var k in json){
+ DATA.card_comments[k] = json[k];
+ }
+ showComments();
+ });
+}
+
+function isShiJian(title){
+ return title.indexOf('')!=-1 && title.indexOf('[')!=-1 && title.indexOf(']')!=-1;
+}
+
+//显示评论内容
+//var showCommentsType;
+//function showComments(){
+// var comments = [];
+// var shijianNum=0;
+// var dongtaiNum=0;
+//
+// if(!DATA.card_comments)return;
+// for(var k in DATA.card_comments){
+// if(DATA.card_comments[k].cardId == DATA.lastShowCardID){
+// comments.push( DATA.card_comments[k] );
+//
+// if(isShiJian(DATA.card_comments[k].text)){
+// shijianNum++;
+// }else{
+// dongtaiNum++;
+// }
+// }
+// }
+//
+// console.log('shijianNum',shijianNum);
+// console.log('dongtaiNum',dongtaiNum);
+//
+// comments.sort(function(a,b){
+// return b.createdAt.sec - a.createdAt.sec;
+// });
+//
+// fill('#tmpl-cardinfo_comments',comments,'#cardinfo_comments_panel');
+// $('#cardinfo_comments_panel').viewer({
+// viewed:function() {
+// $('#cardinfo').css('overflow-y','visible');
+// },
+// hide:function(){
+// $('#cardinfo').css('overflow-y','auto');
+// }
+// });
+//}
+
+//格式化检查项
+function fmtCheckListByCardID(cardid){
+ $.get('./?app=api&apiact=get_checklists&cardid='+cardid,function(text){
+ var json = JSON.parse( text );
+ DATA.card_checklists = DATA.card_checklists || {};
+ for(var k in json){
+ DATA.card_checklists[k] = json[k];
+ }
+ showCheckList();
+ });
+}
+
+//显示评论内容
+function showComments(){
+ if(!DATA.card_comments)return;
+ var shijian=[];
+ var dongtai=[];
+ var comments = [];
+ for(var k in DATA.card_comments){
+ if(DATA.card_comments[k].cardId == DATA.lastShowCardID){
+ comments.push( DATA.card_comments[k] );
+ if(isShiJian(DATA.card_comments[k].text)){
+ shijian.push( DATA.card_comments[k] );
+ }else{
+ dongtai.push( DATA.card_comments[k] );
+ }
+ }
+ }
+
+
+ if(showCommentsType=='all'){
+
+ }else if(showCommentsType=='shijian'){
+ comments = shijian;
+ }else if(showCommentsType=='dongtai' || showCommentsType=='default'){
+ comments = dongtai;
+ if( dongtai.length==0 && showCommentsType=='default'){
+ showCommentsType = 'shijian';
+ comments = shijian;
+ }else{
+ showCommentsType = "dongtai";
+ }
+ }
+
+ $('.detail_lis').removeClass('on');
+ $('.detail_lis_'+showCommentsType).addClass('on')
+
+ comments.sort(function(a,b){
+ return b.createdAt.sec - a.createdAt.sec;
+ });
+
+ fill('#tmpl-cardinfo_comments',comments,'#cardinfo_comments_panel');
+ $('#cardinfo_comments_panel').viewer({
+ viewed:function() {
+ $('#cardinfo').css('overflow-y','visible');
+ },
+ hide:function(){
+ $('#cardinfo').css('overflow-y','auto');
+ }
+ });
+}
+
+//显示检查项
+function showCheckList(){
+ var contents = [];
+ if(!DATA.card_checklists)return;
+ for(var k in DATA.card_checklists){
+ if(DATA.card_checklists[k].cardId == DATA.lastShowCardID){
+ contents.push( DATA.card_checklists[k] );
+ }
+ }
+ contents.sort(function(a,b){
+ if(a.sort != b.sort){
+ return a.sort-b.sort;
+ }else{
+ return a._id > b._id ? -1 : 1;
+ }
+ });
+
+ var html = [];
+ for(var i=0;i '+ (contents[i].isFinished?'':"") + contents[i].title + (contents[i].isFinished?' ':"") +' ');
+ }
+
+ $('#checklistsol').html( html.join('') );
+}
+
+function setDescription( data ){
+ $('.cardinfo_description').html( replaceImgURL(marked(data['description']||'点击编辑')) );
+
+ $('.cardinfo_description').viewer({
+ viewed:function() {
+ $('#cardinfo').css('overflow-y','visible');
+ },
+ hide:function(){
+ $('#cardinfo').css('overflow-y','auto');
+ }
+ });
+
+ if(HOST!='10.0.0.5'){
+ $('.cardinfo_description a').unbind().each(function(index,o){
+
+ if(o.href.indexOf('url.cn')!=-1){
+ //内网文档
+ $.get('./?app=short2long&url='+encodeURIComponent(o.href),function(longurl){
+ console.log('longurl',longurl);
+ if(longurl!="" && longurl.indexOf('10.0.0.5')!=-1){
+ o.href = longurl.replace('10.0.0.5','myip.legu.cc:81');
+ o.innerHTML += '[已重置为异地办公模式]';
+ }
+ });
+ }
+ });
+ }
+
+}
+
+function timetrans(date) {// 格式化日期
+ var date = new Date(date*1000);
+ var YY = date.getFullYear() + '-';
+ var MM = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
+ var DD = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate());
+ var hh = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
+ var mm = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
+ var ss = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());
+ return MM + DD +" "+ hh + mm + ss;
+}
+
+function setCardInfoTitle( data ){
+ $('.cardinfo_title').html( data['title']||'无' );
+ console.log('data',data);
+ $('.cardinfo_ctime').html( timetrans(data['createdAt'].sec) ||'' );
+}
+
+
+function checkats(text){
+ var ats = text.match(/@(\S*)\s{1}/g);
+ var tousers = [];
+ if(window.MYINFO && ats && ats.length>0){
+ for(var i=0;i0){
+ var msgInfo = window.MYINFO.profile.fullname + "在任务["+ DATA.cards[ DATA.lastShowCardID ].title+']中提到了你:'+ text;
+ sendDDMSG(tousers.join(','),msgInfo,location.href);
+ }
+ }
+}
+
+//提交评论
+function doSubmitCommonts(text,boardid,cardid,callback){
+ if(boardid==null){boardid = DATA.cards[cardid].boardId;} //兼容“与我相关“模式
+ checkats(text);
+ $.get('./?app=api&apiact=add_card_comments&cardid='+cardid+"&boardid="+boardid+"&text="+ encodeURIComponent(text),function(text){
+ var json = JSON.parse( text );
+ emitEventByJSON(json);
+ callback && callback(json);
+ });
+}
+//修改描述
+function doSubmitDescription(text,boardid,cardid,callback){
+ if(boardid==null){boardid = DATA.cards[cardid].boardId;} //兼容“与我相关“模式
+ checkats(text);
+ var newDescription = text;
+ var oldDescription = DATA.cards[cardid].description;
+ $.get('./?app=api&apiact=set_card_description&cardid='+cardid+"&boardid="+boardid+"&text="+ encodeURIComponent(text),function(text){
+ var json = JSON.parse( text );
+ if (newDescription != oldDescription){
+ var myinfo = getUserInfo( MYID );
+ var info = myinfo.profile.fullname || "我";
+
+ // console.log('oldDescription',oldDescription);
+
+ if(oldDescription){
+ info += '[修改了描述] ';
+ info += '```'+ oldDescription +'```' + ' 为 ```' + newDescription + '```';
+
+ }else {
+ info += '[添加了描述] ';
+ info += '```' + newDescription + '```';
+
+ }
+
+ doSubmitCommonts( info, DATA.boardid, cardid );
+ }
+
+ emitEventByJSON(json);
+ callback && callback(json);
+ });
+}
+//修改标题
+function doSubmitTitle(text,boardid,cardid,callback){
+ var uid = window.MYINFO._id;
+ var newTitle = text;
+ var oldTitle = DATA.cards[cardid].title;
+ if(boardid==null){boardid = DATA.cards[cardid].boardId;} //兼容“与我相关“模式
+ // $.get('./?app=api&apiact=set_card_title&cardid='+cardid+"&boardid="+boardid+"&text="+ encodeURIComponent(text),function(text){
+ $.get('./?app=api&apiact=set_card_title&cardid='+cardid+"&boardid="+boardid+"&uid="+uid+"&text="+ encodeURIComponent(text),function(text){
+ var json = JSON.parse( text );
+
+ if (newTitle != oldTitle){
+ var myinfo = getUserInfo( MYID );
+ var info = myinfo.profile.fullname || "我";
+ info += '[修改了标题] ';
+ info += ''+ oldTitle +' ' + ' 为 ' + newTitle + ' ';
+
+ // console.log('aaaa', json);
+
+ doSubmitCommonts( info, DATA.boardid, cardid );
+ }
+
+
+ emitEventByJSON(json);
+ callback && callback(json);
+ });
+}
+//删除附件
+function doSubmitDelFuJian(cardid,fujianid,callback){
+ $.get('./?app=api&apiact=del_fujian&cardid='+cardid+"&fujianid="+fujianid,function(text){
+ var json = JSON.parse( text );
+ emitEventByJSON(json);
+ callback && callback(json);
+ });
+}
+
+//新增检查项
+function doSubmitAddChecklist(text,cardid,callback,sort){
+ if(sort==null)sort="";
+ $.get('./?app=api&apiact=add_card_checklist&sort='+ sort+'&cardid='+cardid+"&text="+ encodeURIComponent(text),function(text){
+ var json = JSON.parse( text );
+ emitEventByJSON(json);
+ callback && callback(json);
+ });
+}
+
+function doSubmitSetFickshChecklist(checkid,val,callback){
+ $.get('./?app=api&apiact=set_checklist_finish&id='+checkid+"&val="+ val,function(text){
+ var json = JSON.parse( text );
+ emitEventByJSON(json);
+ callback && callback(json);
+ });
+}
+
+function doSubmitDelChecklist(id,callback){
+ $.get('./?app=api&apiact=del_checklist&id='+id,function(text){
+ var json = JSON.parse( text );
+ emitEventByJSON(json);
+ callback && callback(json);
+ });
+}
+
+function setMemTimer(val,obj,callback){
+ var memid = $(obj).data('id');
+ var cardid = $(obj).parents('.card,#cardinfo').data('id');
+
+
+ console.log('memid',memid);
+ console.log('cardid',cardid);
+ if(!memid || !cardid)return;
+
+ var times = '',timee='';
+ if(val){
+ var arr = val.split('~');
+ times = arr[0];
+ timee = arr[1];
+ }
+
+ $.get('./?app=api&apiact=set_mem_time×='+ times +'&timee='+ timee +'&cardid='+cardid+"&memid="+memid,function(text){
+ var json = JSON.parse( text );
+ emitEventByJSON(json);
+ callback && callback(json);
+ var setText = '设置了[时间] 卡片' + times + ' / ' + timee;
+ doSubmitCommonts(setText,DATA.boardid,cardid);
+ });
+}
+
+
+// 是否设置了QA标签
+function isSetQALabel(cid){
+ var qalabelIds = DATA.cards[cid].qalabelIds;
+ if (!qalabelIds || qalabelIds.length <= 0){
+ return false;
+ }
+ return true;
+
+}
+
+// 检查当前用户是否是QA
+function isQA(){
+ if(window.MYINFO && window.MYINFO.legulabel && window.MYINFO._id){
+ var pms = 'QAlabels';
+ var uid = window.MYINFO._id;
+ $.get('./?app=api&apiact=getWorkPermission&uid=' + uid + '&pms=' + pms,function (txt) {
+ var isAllow = JSON.parse(txt);
+ console.log('isAQ------'+ isAllow);
+ if (isAllow){
+ return true;
+ }
+ });
+
+ }else {
+ return false;
+ }
+
+}
+
+// 检查是否是QA
+function checkQA(callback,uid){
+ callback && callback(true);
+
+ /*if(window.MYINFO && window.MYINFO.legulabel && window.MYINFO._id) {
+
+ var pms = 'QAlabels';
+ var ckuid = uid || window.MYINFO._id;
+ $.get('./?app=api&apiact=getWorkPermission&uid=' + ckuid + '&pms=' + pms, function (txt) {
+ var isAllow = JSON.parse(txt);
+ // console.log('isAQ------' + isAllow);
+ if (isAllow) {
+ // callback && callback(isAllow);
+ }
+ callback && callback(isAllow);
+ });
+ }
+ */
+}
+
+
+function checkPermission(pms,callback){
+ var uid = window.MYINFO._id;
+ $.get('./?app=api&apiact=getWorkPermission&uid=' + uid + '&pms=' + pms, function (txt) {
+ var isAllow = JSON.parse(txt);
+ // console.log('isAQ------' + isAllow);
+ if (isAllow) {
+ // callback && callback(isAllow);
+ }
+ callback && callback(isAllow);
+ });
+}
+
+// 未完成的卡片关闭的时候检查状态
+function checkUnfinishedCardCanClose(callback){
+ callback && callback({});
+ var cardid = DATA.lastShowCardID;
+
+
+ if(DATA.cards[cardid] && DATA.cards[cardid] && DATA.cards[cardid].qalabelIds){
+ if(!DATA.cards[cardid].qalabelIds || DATA.cards[cardid].qalabelIds.length == 0){
+ alert('请添加【问题类型】');
+ return;
+ }
+ }
+
+ if(DATA.cards[cardid] && DATA.cards[cardid]._status && DATA.cards[cardid]._status == 'unfinished'){
+ // 标题
+ // if(DATA.cards[cardid].title == DC.unfinishedTitle || DATA.cards[cardid].title == '' || DATA.cards[cardid].title == '无'){
+ // alert('请修改标题');
+ // return;
+ // }
+
+ // 部分看板
+ // 是否检查 《xx》看板要检查
+ var isCheck = true;
+ var boardTitle = DATA.boards[DATA.boardid].title;
+ var isCheckBoardTitle = boardTitle.match(/《(\S*?)》/g);
+ if (!isCheckBoardTitle || isCheckBoardTitle.length == 0){
+ isCheck = false;
+ }
+
+
+ // var title = DATA.cards[cardid].title.match(/【(\S+?)】/g);
+ var title = DATA.cards[cardid].title;
+ if(isCheck){
+ if ((!title || title.length == 0)){
+ alert('请添加【标题】');
+ return;
+ }
+
+ // qa标签
+ if((!DATA.cards[cardid].qalabelIds || DATA.cards[cardid].qalabelIds.length == 0)){
+ alert('请对创建的单子添加【问题类型】');
+ return;
+ }
+
+ // 根据qa标签是否检查描述
+ // bug和其他不检查
+ board = DATA.boards[DATA.cards[cardid].boardId];
+ // var linfo = board.qalabels[DATA.cards[cardid].qalabelIds[0]];
+ // 只有一个qa标签
+ var lid = DATA.cards[cardid].qalabelIds[0];
+ for(var l=0;l -1)) {
+ // 描述不能为空
+ if (!DATA.cards[cardid].description || !DATA.cards[cardid].description.trim()) {
+ alert('请添加单子详细【描述】(最好带截图)');
+ return;
+ }
+ }
+ }
+ }
+
+ // 部门标签
+ if((!DATA.cards[cardid].labelIds || DATA.cards[cardid].labelIds.length == 0)){
+ alert('请对创建的单子添加【部门标签】');
+ return;
+ }
+
+
+ }
+
+
+ // 验证完了 修改类型
+ boardid = '';
+ uid = '';
+ $.get('./?app=api&apiact=set_card_status&cardid='+cardid+"&boardid="+boardid+"&uid="+uid,function(text){
+ //if(cards[cardid].risklabelsId.length>1){
+ // alert('请将风险标签去除后再来打勾勾哦~');
+ //}
+ var json = JSON.parse( text );
+ emitEventByJSON(json);
+ callback && callback(json);
+ });
+
+
+ // var title = DATA.cards[cardid].title.match(/【(\S*?)】/g);
+ // if (isCheck && (!title || title.length == 0)){
+ // alert('请修改标题 【模块】标题');
+ // return;
+ // }
+ //
+ // // qa标签
+ // if(isCheck && (!DATA.cards[cardid].qalabelIds || DATA.cards[cardid].qalabelIds.length == 0)){
+ // alert('请对创建的单子添加问题类型');
+ // return;
+ // }
+ // // 验证完了 修改类型
+ boardid = '';
+ uid = '';
+ $.get('./?app=api&apiact=set_card_status&cardid='+cardid+"&boardid="+boardid+"&uid="+uid,function(text){
+ var json = JSON.parse( text );
+ emitEventByJSON(json);
+ callback && callback(json);
+ });
+
+
+ }
+
+ $('#firstAddQaLabels').hide();
+
+ callback && callback();
+
+}
+
+// 检查状态是未完成的单子是否可点开
+function checkUnfinishedCardCanClick(cardid, callback){
+ // 状态是未完成且不是自己创建的单子不能点开
+ // 添加了描述和部门就能点开
+ if(DATA.cards[cardid] && DATA.cards[cardid]._status=='show' || DATA.cards[cardid] && DATA.cards[cardid]._status==undefined){
+
+ }
+ else if(DATA.cards[cardid] && (DATA.cards[cardid].description==undefined || !DATA.cards[cardid].labelIds.length) && DATA.cards[cardid].userId != window.MYINFO._id){
+ alert('该单子未创建完成');
+ return;
+ }
+ callback && callback();
+}
+
+
+
+$(function(){
+
+ checkQA(function (isAllow) {
+ DC.permission.QAlabels = isAllow
+ });
+
+
+ $('body').on("click","#cardinfoClose",function(){
+ checkUnfinishedCardCanClose(function () {
+ closeCardInfo();
+ });
+ });
+
+ $('body').on("click","#cardinfoDelete",function(){
+
+ var that = $(this);
+ var cid = DATA.lastShowCardID;
+
+ if(MYID!=DATA.cards[cid].userId){
+ alert('不是你的单子你删不掉');
+ return
+ }
+
+ if(confirm("确定删除吗?")){
+
+
+ // var listid = $(this).parents('.listmenu').data('id');
+ // doSubmitArchivedOveredCards(listid,function(){
+ // $('.close_menu_li').click();
+ // });
+
+ doSubmitDeleteCards(cid,function () {
+ $('#cardinfoClose').click();
+ })
+ }
+
+
+
+ });
+
+
+ $('body').on("click","#cardinfoOverd",function(){
+ var that = $(this);
+ var lid = DATA.lastShowCardID;
+
+ // if (isQA()){
+ // if (!isSetQALabel(lid)){
+ // alert('请设置问题类型');
+ // return;
+ // }
+ // }
+ var cardid = lid;
+
+ // ui验 美验
+ var card = DATA.cards[ DATA.lastShowCardID ];
+ var board = DATA.boards[ card.boardId ];
+ var board_id_name = {};
+ for (var i of board.labels){
+ board_id_name[i['_id']] = i['name'];
+ }
+ // 已经设置的标签 再次点击是去除标签
+ for (var clid of card.labelIds){
+ var labelName = board_id_name[clid];
+ var isOk = checkMeiShuLabelRemove(labelName);
+ if(!isOk){
+ return;
+ }
+ }
+
+ //完成该卡片
+ if(confirm('删除所有标签并设为完成?')){
+ // var lid = DATA.lastShowCardID;
+ // var labels = DATA.cards[lid].labelIds;
+ // for(var i=0;i0)_add();
+ },index);
+ index++;
+ }
+ _add();
+ };
+
+ $('body').on('click','.checklistcheckbox',function(){
+ var val = $(this).prop('checked');
+ var _id = $(this).data('id');
+ doSubmitSetFickshChecklist(_id,val,function(){
+
+ });
+ });
+
+ $('body').on('click','.delchecklist',function(){
+ var _id = $(this).parent().find('.checklistcheckbox').data('id');
+ doSubmitDelChecklist(_id,function(){
+
+ });
+ });
+
+ $('body').on('click','.detail_lis_dongtai',function(){
+ //动态
+ showCommentsType = 'dongtai';
+ showComments();
+
+ });
+ $('body').on('click','.detail_lis_shijian',function(){
+ //事件
+ showCommentsType = 'shijian';
+ showComments();
+ });
+ $('body').on('click','.detail_lis_all',function(){
+ //全部评论
+ showCommentsType = 'all';
+ showComments();
+ });
+
+
+ EVENT.on('addcomment',function(data){
+ if(data.cardId != DATA.lastShowCardID && DATA.boardid!=null)return;
+ showComments();
+ });
+
+ EVENT.on('addchecklist',function(data){
+ if(data.cardId != DATA.lastShowCardID && DATA.boardid!=null)return;
+ showCheckList();
+ });
+
+ EVENT.on('setchecklistfinish',function(data){
+ if(data.cardId != DATA.lastShowCardID && DATA.boardid!=null)return;
+ showCheckList();
+ });
+
+ EVENT.on('delchecklist',function(data){
+ if(data.cardId != DATA.lastShowCardID && DATA.boardid!=null)return;
+ showCheckList();
+ });
+
+ EVENT.on('setdescription',function(data){
+ if(data._id != DATA.lastShowCardID)return;
+ setDescription( data );
+ });
+ EVENT.on('settitle',function(data){
+ if(data._id != DATA.lastShowCardID)return;
+ setCardInfoTitle( data );
+ });
+
+ EVENT.on('memberchange',function(data){
+ if(data.boardId != DATA.boardid && DATA.boardid!=null)return;
+ if(data._id != DATA.lastShowCardID)return;
+ _fmtCardInfoMembersByCardID();
+ });
+
+ EVENT.on('memtimechange',function(data){
+ if(data.boardId != DATA.boardid && DATA.boardid!=null)return;
+ if(data._id != DATA.lastShowCardID)return;
+ _fmtCardInfoMembersByCardID();
+ });
+
+ EVENT.on('labelchange',function(data){
+ if(data.boardId != DATA.boardid && DATA.boardid!=null)return;
+ if(data._id != DATA.lastShowCardID)return;
+ _fmtCardInfoLabelsByCardID();
+ _fmtCardInfoQALabelsByCardID();
+ _fmtCardInfoRiskLabelsByCardID();
+ _fmtCardInfoIssueTagsByCardID();
+ });
+
+ EVENT.on('attachmentschange',function(data){
+ if(data.boardId != DATA.boardid && DATA.boardid!=null)return;
+ if(data._id != DATA.lastShowCardID)return;
+
+ showAttachmentsByCardID( data._id );
+ });
+
+
+});
+
+
+function formatDate(time) {
+ var now = new Date(time*1000);
+ var year = now.getFullYear(),
+ month = now.getMonth() + 1,
+ date = now.getDate(),
+ hour = now.getHours(),
+ minute = now.getMinutes(),
+ second = now.getSeconds();
+ return year + "-" + month + "-" + date + " " + hour + ":" + minute + ":" + second;
+}
diff --git a/scripts/colpick.js b/scripts/colpick.js
new file mode 100644
index 0000000..a71dcf4
--- /dev/null
+++ b/scripts/colpick.js
@@ -0,0 +1,561 @@
+/*
+colpick Color Picker
+Copyright 2013 Jose Vargas. Licensed under GPL license. Based on Stefan Petre's Color Picker www.eyecon.ro, dual licensed under the MIT and GPL licenses
+
+For usage and examples: colpick.com/plugin
+ */
+
+(function ($) {
+ var colpick = function () {
+ var
+ tpl = '',
+ defaults = {
+ showEvent: 'click',
+ onShow: function () {},
+ onBeforeShow: function(){},
+ onHide: function () {},
+ onChange: function () {},
+ onSubmit: function () {},
+ colorScheme: 'light',
+ color: '3289c7',
+ livePreview: true,
+ flat: false,
+ layout: 'full',
+ submit: 1,
+ submitText: 'OK',
+ height: 156,
+ hsl: false
+ },
+ //Fill the inputs of the plugin
+ fillRGBFields = function (hsx, cal) {
+ var rgb = $(cal).data('colpick').hsl ? hslToRgb(hsx) : hsbToRgb(hsx);
+ $(cal).data('colpick').fields
+ .eq(1).val(rgb.r).end()
+ .eq(2).val(rgb.g).end()
+ .eq(3).val(rgb.b).end();
+ },
+ fillHSXFields = function (hsx, cal) {
+
+ $(cal).data('colpick').fields
+ .eq(4).val(Math.round(hsx.h)).end()
+ .eq(5).val(Math.round(hsx.s)).end()
+ .eq(6).val(Math.round(hsx.x)).end();
+ },
+ fillHexFields = function (hsx, cal) {
+ $(cal).data('colpick').fields.eq(0).val($(cal).data('colpick').hsl ? hslToHex(hsx) : hsbToHex(hsx));
+ },
+ //Set the round selector position
+ setSelector = function (hsx, cal) {
+ $(cal).data('colpick').selector.css('backgroundColor', '#' + ($(cal).data('colpick').hsl ? hslToHex({h:hsx.h,s:100,x:50}) : hsbToHex({h:hsx.h,s:100,x:100})) );
+ $(cal).data('colpick').selectorIndic.css({
+ left: parseInt($(cal).data('colpick').height * hsx.s/100, 10),
+ top: parseInt($(cal).data('colpick').height * (100-hsx.x)/100, 10)
+ });
+ },
+ //Set the hue selector position
+ setHue = function (hsx, cal) {
+ $(cal).data('colpick').hue.css('top', parseInt($(cal).data('colpick').height - $(cal).data('colpick').height * hsx.h/360, 10));
+ },
+ //Set current and new colors
+ setCurrentColor = function (hsx, cal) {
+ $(cal).data('colpick').currentColor.css('backgroundColor', '#' + ($(cal).data('colpick').hsl ? hslToHex(hsx) : hsbToHex(hsx)) );
+ },
+ setNewColor = function (hsx, cal) {
+ $(cal).data('colpick').newColor.css('backgroundColor', '#' + ($(cal).data('colpick').hsl ? hslToHex(hsx) : hsbToHex(hsx)) );
+ },
+ //Called when the new color is changed
+ change = function (ev) {
+ var cal = $(this).parent().parent(), col;
+ if (this.parentNode.className.indexOf('_hex') > 0) {
+ cal.data('colpick').color = col = cal.data('colpick').hsl ? hexToHsl(fixHex(this.value)) : hexToHsb(fixHex(this.value));
+ fillRGBFields(col, cal.get(0));
+ fillHSXFields(col, cal.get(0));
+ } else if (this.parentNode.className.indexOf('_hsx') > 0) {
+ cal.data('colpick').color = col = fixHsx({
+ h: parseInt(cal.data('colpick').fields.eq(4).val(), 10),
+ s: parseInt(cal.data('colpick').fields.eq(5).val(), 10),
+ x: parseInt(cal.data('colpick').fields.eq(6).val(), 10)
+ });
+ fillRGBFields(col, cal.get(0));
+ fillHexFields(col, cal.get(0));
+ } else {
+ var rgb = {
+ r: parseInt(cal.data('colpick').fields.eq(1).val(), 10),
+ g: parseInt(cal.data('colpick').fields.eq(2).val(), 10),
+ b: parseInt(cal.data('colpick').fields.eq(3).val(), 10)
+ };
+ cal.data('colpick').color = col = cal.data('colpick').hsl ? rgbToHsl(fixRgb(rgb)) : rgbToHsb(fixRgb(rgb));
+ fillHexFields(col, cal.get(0));
+ fillHSXFields(col, cal.get(0));
+ }
+ setSelector(col, cal.get(0));
+ setHue(col, cal.get(0));
+ setNewColor(col, cal.get(0));
+ cal.data('colpick').onChange.apply(cal.parent(), [col, cal.data('colpick').hsl ? hslToHex(col) : hsbToHex(col), cal.data('colpick').hsl ? hslToRgb(col) : hsbToRgb(col), cal.data('colpick').el, 0]);
+ },
+ //Change style on blur and on focus of inputs
+ blur = function (ev) {
+ $(this).parent().removeClass('colpick_focus');
+ },
+ focus = function () {
+ $(this).parent().parent().data('colpick').fields.parent().removeClass('colpick_focus');
+ $(this).parent().addClass('colpick_focus');
+ },
+ //Increment/decrement arrows functions
+ downIncrement = function (ev) {
+ ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;
+ var field = $(this).parent().find('input').focus();
+ var current = {
+ el: $(this).parent().addClass('colpick_slider'),
+ max: this.parentNode.className.indexOf('_hsx_h') > 0 ? 360 : (this.parentNode.className.indexOf('_hsx') > 0 ? 100 : 255),
+ y: ev.pageY,
+ field: field,
+ val: parseInt(field.val(), 10),
+ preview: $(this).parent().parent().data('colpick').livePreview
+ };
+ $(document).mouseup(current, upIncrement);
+ $(document).mousemove(current, moveIncrement);
+ },
+ moveIncrement = function (ev) {
+ ev.data.field.val(Math.max(0, Math.min(ev.data.max, parseInt(ev.data.val - ev.pageY + ev.data.y, 10))));
+ if (ev.data.preview) {
+ change.apply(ev.data.field.get(0), [true]);
+ }
+ return false;
+ },
+ upIncrement = function (ev) {
+ change.apply(ev.data.field.get(0), [true]);
+ ev.data.el.removeClass('colpick_slider').find('input').focus();
+ $(document).off('mouseup', upIncrement);
+ $(document).off('mousemove', moveIncrement);
+ return false;
+ },
+ //Hue slider functions
+ downHue = function (ev) {
+ ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;
+ var current = {
+ cal: $(this).parent(),
+ y: $(this).offset().top
+ };
+ $(document).on('mouseup touchend',current,upHue);
+ $(document).on('mousemove touchmove',current,moveHue);
+
+ var pageY = ((ev.type == 'touchstart') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY );
+ change.apply(
+ current.cal.data('colpick')
+ .fields.eq(4).val(parseInt(360*(current.cal.data('colpick').height - (pageY - current.y))/current.cal.data('colpick').height, 10))
+ .get(0),
+ [current.cal.data('colpick').livePreview]
+ );
+ return false;
+ },
+ moveHue = function (ev) {
+ var pageY = ((ev.type == 'touchmove') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY );
+ change.apply(
+ ev.data.cal.data('colpick')
+ .fields.eq(4).val(parseInt(360*(ev.data.cal.data('colpick').height - Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageY - ev.data.y))))/ev.data.cal.data('colpick').height, 10))
+ .get(0),
+ [ev.data.preview]
+ );
+ return false;
+ },
+ upHue = function (ev) {
+ //fillRGBFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0));
+ //fillHexFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0));
+ $(document).off('mouseup touchend',upHue);
+ $(document).off('mousemove touchmove',moveHue);
+ return false;
+ },
+ //Color selector functions
+ downSelector = function (ev) {
+ ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;
+ var current = {
+ cal: $(this).parent(),
+ pos: $(this).offset()
+ };
+ current.preview = current.cal.data('colpick').livePreview;
+
+ $(document).on('mouseup touchend',current,upSelector);
+ $(document).on('mousemove touchmove',current,moveSelector);
+
+ var payeX,pageY;
+ if(ev.type == 'touchstart') {
+ pageX = ev.originalEvent.changedTouches[0].pageX,
+ pageY = ev.originalEvent.changedTouches[0].pageY;
+ } else {
+ pageX = ev.pageX;
+ pageY = ev.pageY;
+ }
+
+ change.apply(
+ current.cal.data('colpick').fields
+ .eq(6).val(parseInt(100*(current.cal.data('colpick').height - (pageY - current.pos.top))/current.cal.data('colpick').height, 10)).end()
+ .eq(5).val(parseInt(100*(pageX - current.pos.left)/current.cal.data('colpick').height, 10))
+ .get(0),
+ [current.preview]
+ );
+ return false;
+ },
+ moveSelector = function (ev) {
+ var payeX,pageY;
+ if(ev.type == 'touchmove') {
+ pageX = ev.originalEvent.changedTouches[0].pageX,
+ pageY = ev.originalEvent.changedTouches[0].pageY;
+ } else {
+ pageX = ev.pageX;
+ pageY = ev.pageY;
+ }
+
+ change.apply(
+ ev.data.cal.data('colpick').fields
+ .eq(6).val(parseInt(100*(ev.data.cal.data('colpick').height - Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageY - ev.data.pos.top))))/ev.data.cal.data('colpick').height, 10)).end()
+ .eq(5).val(parseInt(100*(Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageX - ev.data.pos.left))))/ev.data.cal.data('colpick').height, 10))
+ .get(0),
+ [ev.data.preview]
+ );
+ return false;
+ },
+ upSelector = function (ev) {
+ //fillRGBFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0));
+ //fillHexFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0));
+ $(document).off('mouseup touchend',upSelector);
+ $(document).off('mousemove touchmove',moveSelector);
+ return false;
+ },
+ //Submit button
+ clickSubmit = function (ev) {
+ var cal = $(this).parent();
+ var col = cal.data('colpick').color;
+ cal.data('colpick').origColor = col;
+ setCurrentColor(col, cal.get(0));
+ cal.data('colpick').onSubmit(col, cal.data('colpick').hsl ? hslToHex(col) : hsbToHex(col), cal.data('colpick').hsl ? hslToRgb(col) : hsbToRgb(col), cal.data('colpick').el);
+ },
+ //Show/hide the color picker
+ show = function (ev) {
+ // Prevent the trigger of any direct parent
+ ev.stopPropagation();
+ var cal = $('#' + $(this).data('colpickId'));
+ cal.data('colpick').onBeforeShow.apply(this, [cal.get(0)]);
+ var pos = $(this).offset();
+ var top = pos.top + this.offsetHeight;
+ var left = pos.left;
+ var viewPort = getViewport();
+ var calW = cal.width();
+ if (left + calW > viewPort.l + viewPort.w) {
+ left -= calW;
+ }
+ cal.css({left: left + 'px', top: top + 'px'});
+ if (cal.data('colpick').onShow.apply(this, [cal.get(0)]) != false) {
+ cal.show();
+ }
+ //Hide when user clicks outside
+ $('html').mousedown({cal:cal}, hide);
+ cal.mousedown(function(ev){ev.stopPropagation();})
+ },
+ hide = function (ev) {
+ if (ev.data.cal.data('colpick').onHide.apply(this, [ev.data.cal.get(0)]) != false) {
+ ev.data.cal.hide();
+ }
+ $('html').off('mousedown', hide);
+ },
+ getViewport = function () {
+ var m = document.compatMode == 'CSS1Compat';
+ return {
+ l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft),
+ w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth)
+ };
+ },
+ //Fix the values if the user enters a negative or high value
+ fixHsx = function (hsx) {
+ return {
+ h: Math.min(360, Math.max(0, hsx.h)),
+ s: Math.min(100, Math.max(0, hsx.s)),
+ x: Math.min(100, Math.max(0, hsx.x))
+ };
+ },
+ fixRgb = function (rgb) {
+ return {
+ r: Math.min(255, Math.max(0, rgb.r)),
+ g: Math.min(255, Math.max(0, rgb.g)),
+ b: Math.min(255, Math.max(0, rgb.b))
+ };
+ },
+ fixHex = function (hex) {
+ var len = 6 - hex.length;
+ if (len > 0) {
+ var o = [];
+ for (var i=0; i ').attr('style','height:8.333333%; filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='+stops[i]+', endColorstr='+stops[i+1]+'); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='+stops[i]+', endColorstr='+stops[i+1]+')";');
+ huebar.append(div);
+ }
+ } else {
+ stopList = stops.join(',');
+ huebar.attr('style','background:-webkit-linear-gradient(top center,'+stopList+'); background:-moz-linear-gradient(top center,'+stopList+'); background:linear-gradient(to bottom,'+stopList+'); ');
+ }
+ cal.find('div.colpick_hue').on('mousedown touchstart',downHue);
+ options.newColor = cal.find('div.colpick_new_color');
+ options.currentColor = cal.find('div.colpick_current_color');
+ //Store options and fill with default color
+ cal.data('colpick', options);
+ fillRGBFields(options.color, cal.get(0));
+ fillHSXFields(options.color, cal.get(0));
+ fillHexFields(options.color, cal.get(0));
+ setHue(options.color, cal.get(0));
+ setSelector(options.color, cal.get(0));
+ setCurrentColor(options.color, cal.get(0));
+ setNewColor(options.color, cal.get(0));
+ //Append to body if flat=false, else show in place
+ if (options.flat) {
+ cal.appendTo(this).show();
+ cal.css({
+ position: 'relative',
+ display: 'block'
+ });
+ } else {
+ cal.appendTo(document.body);
+ $(this).on(options.showEvent, show);
+ cal.css({
+ position:'absolute'
+ });
+ }
+ }
+ });
+ },
+ //Shows the picker
+ showPicker: function() {
+ return this.each( function () {
+ if ($(this).data('colpickId')) {
+ show.apply(this);
+ }
+ });
+ },
+ //Hides the picker
+ hidePicker: function() {
+ return this.each( function () {
+ if ($(this).data('colpickId')) {
+ $('#' + $(this).data('colpickId')).hide();
+ }
+ });
+ },
+ //Sets a color as new and current (default)
+ setColor: function(col, setCurrent) {
+ setCurrent = (typeof setCurrent === "undefined") ? 1 : setCurrent;
+ if (typeof col == 'string') {
+ col = hexToHsb(col);
+ } else if (col.r != undefined && col.g != undefined && col.b != undefined) {
+ col = rgbToHsb(col);
+ } else if (col.h != undefined && col.s != undefined && col.b != undefined) {
+ col = fixHsb(col);
+ } else {
+ return this;
+ }
+ return this.each(function(){
+ if ($(this).data('colpickId')) {
+ var cal = $('#' + $(this).data('colpickId'));
+ cal.data('colpick').color = col;
+ cal.data('colpick').origColor = col;
+ fillRGBFields(col, cal.get(0));
+ fillHSXFields(col, cal.get(0));
+ fillHexFields(col, cal.get(0));
+ setHue(col, cal.get(0));
+ setSelector(col, cal.get(0));
+
+ setNewColor(col, cal.get(0));
+ cal.data('colpick').onChange.apply(cal.parent(), [
+ col,
+ cal.data('colpick').hsl ? hslToHex(col) : hsbToHex(col),
+ cal.data('colpick').hsl ? hslToRgb(col) : hsbToRgb(col),
+ cal.data('colpick').el,
+ 1
+ ]);
+ if(setCurrent) {
+ setCurrentColor(col, cal.get(0));
+ }
+ }
+ });
+ }
+ };
+ }();
+ //Color space convertions
+ var hexToRgb = function (hex) {
+ var hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
+ return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)};
+ };
+ var hexToHsb = function (hex) {
+ return rgbToHsb(hexToRgb(hex));
+ };
+ var hexToHsl = function (hex) {
+ return rgbToHsl(hexToRgb(hex));
+ };
+ var rgbToHsb = function (rgb) {
+ var hsb = {h: 0, s: 0, x: 0};
+ var min = Math.min(rgb.r, rgb.g, rgb.b);
+ var max = Math.max(rgb.r, rgb.g, rgb.b);
+ var delta = max - min;
+ hsb.x = max;
+ hsb.s = max != 0 ? 255 * delta / max : 0;
+ if (hsb.s != 0) {
+ if (rgb.r == max) hsb.h = (rgb.g - rgb.b) / delta;
+ else if (rgb.g == max) hsb.h = 2 + (rgb.b - rgb.r) / delta;
+ else hsb.h = 4 + (rgb.r - rgb.g) / delta;
+ } else hsb.h = -1;
+ hsb.h *= 60;
+ if (hsb.h < 0) hsb.h += 360;
+ hsb.s *= 100/255;
+ hsb.x *= 100/255;
+ return hsb;
+ };
+ var rgbToHsl = function (rgb) {
+ return hsbToHsl(rgbToHsb(rgb));
+ };
+ var hsbToHsl = function(hsb) {
+ var hsl = {h: 0, s: 0, x: 0};
+ hsl.h = hsb.h;
+ hsl.x = hsb.x*(200-hsb.s)/200;
+ hsl.s = hsb.x*hsb.s/(100-Math.abs(2*hsl.x-100));
+ return hsl;
+ };
+ var hslToHsb = function(hsl) {
+ var hsb = {h: 0, s: 0, x: 0};
+ hsb.h = hsl.h;
+ hsb.x = (200*hsl.x + hsl.s*(100-Math.abs(2*hsl.x-100)))/200
+ hsb.s = 200*(hsb.x-hsl.x)/hsb.x;
+ return hsb;
+ };
+ var hsbToRgb = function (hsb) {
+ var rgb = {};
+ var h = hsb.h;
+ var s = hsb.s*255/100;
+ var v = hsb.x*255/100;
+ if(s == 0) {
+ rgb.r = rgb.g = rgb.b = v;
+ } else {
+ var t1 = v;
+ var t2 = (255-s)*v/255;
+ var t3 = (t1-t2)*(h%60)/60;
+ if(h==360) h = 0;
+ if(h<60) {rgb.r=t1; rgb.b=t2; rgb.g=t2+t3}
+ else if(h<120) {rgb.g=t1; rgb.b=t2; rgb.r=t1-t3}
+ else if(h<180) {rgb.g=t1; rgb.r=t2; rgb.b=t2+t3}
+ else if(h<240) {rgb.b=t1; rgb.r=t2; rgb.g=t1-t3}
+ else if(h<300) {rgb.b=t1; rgb.g=t2; rgb.r=t2+t3}
+ else if(h<360) {rgb.r=t1; rgb.g=t2; rgb.b=t1-t3}
+ else {rgb.r=0; rgb.g=0; rgb.b=0}
+ }
+ return {r:Math.round(rgb.r), g:Math.round(rgb.g), b:Math.round(rgb.b)};
+ };
+ var hslToRgb = function(hsl) {
+ return hsbToRgb(hslToHsb(hsl));
+ };
+ var rgbToHex = function (rgb) {
+ var hex = [
+ rgb.r.toString(16),
+ rgb.g.toString(16),
+ rgb.b.toString(16)
+ ];
+ $.each(hex, function (nr, val) {
+ if (val.length == 1) {
+ hex[nr] = '0' + val;
+ }
+ });
+ return hex.join('');
+ };
+ var hsbToHex = function (hsb) {
+ return rgbToHex(hsbToRgb(hsb));
+ };
+ var hslToHex = function (hsl) {
+ return hsbToHex(hslToHsb(hsl));
+ };
+ $.fn.extend({
+ colpick: colpick.init,
+ colpickHide: colpick.hidePicker,
+ colpickShow: colpick.showPicker,
+ colpickSetColor: colpick.setColor
+ });
+ $.extend({
+ colpick:{
+ rgbToHex: rgbToHex,
+ rgbToHsb: rgbToHsb,
+ rgbToHsl: rgbToHsl,
+ hsbToHex: hsbToHex,
+ hsbToRgb: hsbToRgb,
+ hsbToHsl: hsbToHsl,
+ hexToHsb: hexToHsb,
+ hexToHsl: hexToHsl,
+ hexToRgb: hexToRgb,
+ hslToHsb: hslToHsb,
+ hslToRgb: hslToRgb,
+ hslToHex: hslToHex
+ }
+ });
+})(jQuery);
diff --git a/scripts/copy_list_to_new.js b/scripts/copy_list_to_new.js
new file mode 100644
index 0000000..b940729
--- /dev/null
+++ b/scripts/copy_list_to_new.js
@@ -0,0 +1,36 @@
+// 复制到新列
+function copyListToNew(listid){
+
+ console.log('==========');
+ console.log(listid);
+
+ var listTitle = DATA.lists[listid]['title'];
+ var val = listTitle + '复制';
+ // 添加列表
+ doSubmitAddList(val, DATA.boardid, function (listData) {
+ var copyListId = listData['data']['_id'];
+ copyCardData = {};
+ $.extend(copyCardData,DATA.cards);
+ // 添加卡片
+ for (var cardId in copyCardData) {
+ if (copyCardData[cardId].boardId != DATA.boardid) continue;
+ if (copyCardData[cardId].listId != listid) continue;
+ if (copyCardData[cardId].archived) continue;
+
+ var cardTitle = copyCardData[cardId]['title'];
+ var description = '';
+ if (copyCardData[cardId].description){
+ description = copyCardData[cardId].description;
+ }
+ doSubmitAddCardAndDesc(cardTitle,description, DATA.boardid, copyListId, function (cardData) {
+ console.log(cardData);
+ });
+ }
+ });
+
+}
+
+
+
+
+
diff --git a/scripts/diff.js b/scripts/diff.js
new file mode 100644
index 0000000..132213c
--- /dev/null
+++ b/scripts/diff.js
@@ -0,0 +1,1055 @@
+/*!
+
+ diff v2.0.1
+
+Software License Agreement (BSD License)
+
+Copyright (c) 2009-2015, Kevin Decker