连续签到程序逻辑分析以及做任务赚积分程序逻辑分析【完整版】

签到程序逻辑分析 

 流程图SVG代码

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1841px" viewBox="-0.5 -0.5 1841 1561" content="&lt;mxfile&gt;&lt;diagram id=&quot;UFQys8sW3derMFWbF9iM&quot; name=&quot;第 1 页&quot;&gt;&lt;mxGraphModel dx=&quot;1118&quot; dy=&quot;564&quot; grid=&quot;1&quot; gridSize=&quot;10&quot; guides=&quot;1&quot; tooltips=&quot;1&quot; connect=&quot;1&quot; arrows=&quot;1&quot; fold=&quot;1&quot; page=&quot;1&quot; pageScale=&quot;1&quot; pageWidth=&quot;2336&quot; pageHeight=&quot;1654&quot; math=&quot;0&quot; shadow=&quot;0&quot;&gt;&lt;root&gt;&lt;mxCell id=&quot;0&quot;/&gt;&lt;mxCell id=&quot;1&quot; parent=&quot;0&quot;/&gt;&lt;mxCell id=&quot;48&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;43&quot; target=&quot;47&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;50&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;43&quot; target=&quot;49&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;43&quot; value=&quot;【签到天数逻辑判断】&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;verticalAlign=top;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;170&quot; y=&quot;160&quot; width=&quot;1840&quot; height=&quot;500&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;44&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;2&quot; target=&quot;43&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;2&quot; value=&quot;签到-积分添加&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;920&quot; y=&quot;40&quot; width=&quot;120&quot; height=&quot;60&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;4&quot; value=&quot;根据用户ID和当前日期&amp;lt;br&amp;gt;从“签到记录表”获取8天的签到记录&quot; style=&quot;shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;202.5&quot; y=&quot;240&quot; width=&quot;235&quot; height=&quot;60&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;70&quot; value=&quot;是&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;7&quot; target=&quot;16&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;74&quot; value=&quot;否&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;7&quot; target=&quot;68&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;7&quot; value=&quot;判断是否为空&quot; style=&quot;rhombus;whiteSpace=wrap;html=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;270&quot; y=&quot;350&quot; width=&quot;100&quot; height=&quot;80&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;8&quot; value=&quot;&quot; style=&quot;endArrow=classic;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;&quot; parent=&quot;1&quot; source=&quot;4&quot; target=&quot;7&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&lt;mxPoint x=&quot;660&quot; y=&quot;320&quot; as=&quot;sourcePoint&quot;/&gt;&lt;mxPoint x=&quot;710&quot; y=&quot;270&quot; as=&quot;targetPoint&quot;/&gt;&lt;/mxGeometry&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;31&quot; value=&quot;否&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;9&quot; target=&quot;30&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;72&quot; value=&quot;是&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;9&quot; target=&quot;71&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;9&quot; value=&quot;&amp;lt;br&amp;gt;判断“当天日期-1”数据是否为空&amp;lt;br&amp;gt;(即昨天数据)&quot; style=&quot;rhombus;whiteSpace=wrap;html=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;800&quot; y=&quot;320&quot; width=&quot;240&quot; height=&quot;140&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;16&quot; value=&quot;返回:1&quot; style=&quot;shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;230&quot; y=&quot;500&quot; width=&quot;180&quot; height=&quot;70&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;24&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;19&quot; target=&quot;22&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;19&quot; value=&quot;【记录当天签到数据】&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;span&amp;gt;1.用户积分流水表记录&amp;lt;br&amp;gt;2.签到表记录&amp;lt;br&amp;gt;&amp;lt;/span&amp;gt;&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;align=left;spacingLeft=16;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;551&quot; y=&quot;1010&quot; width=&quot;260&quot; height=&quot;120&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;26&quot; style=&quot;edgeStyle=none;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;&quot; parent=&quot;1&quot; source=&quot;22&quot; target=&quot;23&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;22&quot; value=&quot;第一步:&amp;lt;span&amp;gt;用户积分流水表记录,并修改用户积分&amp;lt;br&amp;gt;&amp;lt;/span&amp;gt;&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;align=left;spacingLeft=16;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;541&quot; y=&quot;1210&quot; width=&quot;280&quot; height=&quot;70&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;63&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;23&quot; target=&quot;62&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;23&quot; value=&quot;第二步:&amp;lt;span&amp;gt;签到表记录&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;div&amp;gt;用户Id&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;距离上次打卡相差天数:默认99999&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;是否补签:否&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/span&amp;gt;&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;align=left;spacingLeft=16;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;551&quot; y=&quot;1350&quot; width=&quot;260&quot; height=&quot;120&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;34&quot; value=&quot;是&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;30&quot; target=&quot;32&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;38&quot; value=&quot;否&quot; style=&quot;edgeStyle=none;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;&quot; parent=&quot;1&quot; source=&quot;30&quot; target=&quot;37&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;30&quot; value=&quot;&amp;lt;br&amp;gt;判断“当天日期-2”数据是否为空&amp;lt;br&amp;gt;(即前天数据)&quot; style=&quot;rhombus;whiteSpace=wrap;html=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;1130&quot; y=&quot;320&quot; width=&quot;220&quot; height=&quot;130&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;32&quot; value=&quot;返回:2&quot; style=&quot;shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;1150&quot; y=&quot;500&quot; width=&quot;180&quot; height=&quot;70&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;40&quot; value=&quot;是&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;37&quot; target=&quot;39&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;37&quot; value=&quot;&amp;lt;br&amp;gt;判断“当天日期-3”数据是否为空&amp;lt;br&amp;gt;(即前天数据)&quot; style=&quot;rhombus;whiteSpace=wrap;html=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;1410&quot; y=&quot;320&quot; width=&quot;220&quot; height=&quot;130&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;39&quot; value=&quot;返回:3&quot; style=&quot;shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;1430&quot; y=&quot;500&quot; width=&quot;180&quot; height=&quot;70&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;46&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;45&quot; target=&quot;43&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;45&quot; value=&quot;获取签到天数&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;1198&quot; y=&quot;40&quot; width=&quot;120&quot; height=&quot;60&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;66&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;47&quot; target=&quot;65&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;47&quot; value=&quot;【签到-积分添加】流程继续&quot; style=&quot;shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;551&quot; y=&quot;730&quot; width=&quot;270&quot; height=&quot;60&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;52&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;49&quot; target=&quot;51&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;49&quot; value=&quot;【获取签到天数】流程继续&quot; style=&quot;shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;1329&quot; y=&quot;730&quot; width=&quot;270&quot; height=&quot;60&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;51&quot; value=&quot;接口直接返回该用户的签到天数&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;1293&quot; y=&quot;900&quot; width=&quot;342&quot; height=&quot;60&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;55&quot; value=&quot;提示&quot; style=&quot;swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;1700&quot; y=&quot;400&quot; width=&quot;270&quot; height=&quot;110&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;56&quot; value=&quot;以此类推获取七天内的签到数据&quot; style=&quot;text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;&quot; parent=&quot;55&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry y=&quot;30&quot; width=&quot;270&quot; height=&quot;80&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;62&quot; value=&quot;接口返回:是否执行签到成功&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;510&quot; y=&quot;1540&quot; width=&quot;342&quot; height=&quot;60&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;67&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;65&quot; target=&quot;19&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;65&quot; value=&quot;根据“返回天数”查询“签到天数的积分规则”&quot; style=&quot;shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;546&quot; y=&quot;860&quot; width=&quot;270&quot; height=&quot;60&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;75&quot; value=&quot;否&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;68&quot; target=&quot;9&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;76&quot; value=&quot;是&quot; style=&quot;edgeStyle=none;html=1;&quot; parent=&quot;1&quot; source=&quot;68&quot; target=&quot;73&quot; edge=&quot;1&quot;&gt;&lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;68&quot; value=&quot;&amp;lt;br&amp;gt;判断数据是否为8条&quot; style=&quot;rhombus;whiteSpace=wrap;html=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;480&quot; y=&quot;320&quot; width=&quot;240&quot; height=&quot;140&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;71&quot; value=&quot;返回:1&quot; style=&quot;shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;830&quot; y=&quot;500&quot; width=&quot;180&quot; height=&quot;70&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;mxCell id=&quot;73&quot; value=&quot;返回:1&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;(因为程序是7天为一个周期&amp;lt;br&amp;gt;进行的签到,&amp;lt;br&amp;gt;第八天即为第一天)&quot; style=&quot;shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&lt;mxGeometry x=&quot;510&quot; y=&quot;500&quot; width=&quot;180&quot; height=&quot;80&quot; as=&quot;geometry&quot;/&gt;&lt;/mxCell&gt;&lt;/root&gt;&lt;/mxGraphModel&gt;&lt;/diagram&gt;&lt;/mxfile&gt;" onclick="(function(svg){var src=window.event.target||window.event.srcElement;while (src!=null&amp;&amp;src.nodeName.toLowerCase()!='a'){src=src.parentNode;}if(src==null){if(svg.wnd!=null&amp;&amp;!svg.wnd.closed){svg.wnd.focus();}else{var r=function(evt){if(evt.data=='ready'&amp;&amp;evt.source==svg.wnd){svg.wnd.postMessage(decodeURIComponent(svg.getAttribute('content')),'*');window.removeEventListener('message',r);}};window.addEventListener('message',r);svg.wnd=window.open('https://viewer.diagrams.net/?client=1&amp;page=0&amp;edit=_blank');}}})(this);" style="cursor:pointer;max-width:100%;max-height:1561px;"><defs><clipPath id="mx-clip-1534-390-262-80-0"><rect x="1534" y="390" width="262" height="80"/></clipPath></defs><g><path d="M 631.43 620 L 555.44 685.83" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 551.47 689.27 L 554.47 682.04 L 555.44 685.83 L 559.06 687.33 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 1187.14 620 L 1257.29 685.65" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1261.13 689.24 L 1253.62 687.01 L 1257.29 685.65 L 1258.41 681.9 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="0" y="120" width="1840" height="500" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1838px; height: 1px; padding-top: 127px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">【签到天数逻辑判断】</div></div></div></foreignObject><text x="920" y="139" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">【签到天数逻辑判断】</text></switch></g><path d="M 819.71 60 L 837.16 113.94" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 838.77 118.94 L 833.29 113.35 L 837.16 113.94 L 839.95 111.2 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="750" y="0" width="120" height="60" rx="9" ry="9" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 30px; margin-left: 751px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">签到-积分添加</div></div></div></foreignObject><text x="810" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">签到-积分添加</text></switch></g><path d="M 32.5 260 L 52.5 200 L 267.5 200 L 247.5 260 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 233px; height: 1px; padding-top: 230px; margin-left: 34px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">根据用户ID和当前日期<br />从“签到记录表”获取8天的签到记录</div></div></div></foreignObject><text x="150" y="234" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">根据用户ID和当前日期...</text></switch></g><path d="M 150 390 L 150 453.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 150 458.88 L 146.5 451.88 L 150 453.63 L 153.5 451.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 425px; margin-left: 150px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">是</div></div></div></foreignObject><text x="150" y="428" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">是</text></switch></g><path d="M 200 350 L 303.63 350" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 308.88 350 L 301.88 353.5 L 303.63 350 L 301.88 346.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 350px; margin-left: 255px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">否</div></div></div></foreignObject><text x="255" y="353" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">否</text></switch></g><path d="M 150 310 L 200 350 L 150 390 L 100 350 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 98px; height: 1px; padding-top: 350px; margin-left: 101px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">判断是否为空</div></div></div></foreignObject><text x="150" y="354" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">判断是否为空</text></switch></g><path d="M 150 260 L 150 303.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 150 308.88 L 146.5 301.88 L 150 303.63 L 153.5 301.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 866.87 348.17 L 956.47 346.77" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 961.72 346.69 L 954.77 350.3 L 956.47 346.77 L 954.66 343.3 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 347px; margin-left: 915px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">否</div></div></div></foreignObject><text x="915" y="351" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">否</text></switch></g><path d="M 750 420 L 750 453.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 750 458.88 L 746.5 451.88 L 750 453.63 L 753.5 451.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 440px; margin-left: 750px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">是</div></div></div></foreignObject><text x="750" y="443" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">是</text></switch></g><path d="M 750 280 L 870 350 L 750 420 L 630 350 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 238px; height: 1px; padding-top: 350px; margin-left: 631px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><br />判断“当天日期-1”数据是否为空<br />(即昨天数据)</div></div></div></foreignObject><text x="750" y="354" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">判断“当天日期-1”数据是否为空...</text></switch></g><path d="M 60 530 L 80 460 L 240 460 L 220 530 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 495px; margin-left: 61px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">返回:1</div></div></div></foreignObject><text x="150" y="499" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">返回:1</text></switch></g><path d="M 511 1090 L 511 1163.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 511 1168.88 L 507.5 1161.88 L 511 1163.63 L 514.5 1161.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="381" y="970" width="260" height="120" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 242px; height: 1px; padding-top: 1030px; margin-left: 399px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">【记录当天签到数据】<br /><br /><span>1.用户积分流水表记录<br />2.签到表记录<br /></span></div></div></div></foreignObject><text x="399" y="1034" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">【记录当天签到数据】1.用户积分流水表记录...</text></switch></g><path d="M 511 1240 L 511 1303.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 511 1308.88 L 507.5 1301.88 L 511 1303.63 L 514.5 1301.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="371" y="1170" width="280" height="70" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 262px; height: 1px; padding-top: 1205px; margin-left: 389px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">第一步:<span>用户积分流水表记录,并修改用户积分<br /></span></div></div></div></foreignObject><text x="389" y="1209" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">第一步:用户积分流水表记录,并修改用户积分
</text></switch></g><path d="M 511 1430 L 511 1493.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 511 1498.88 L 507.5 1491.88 L 511 1493.63 L 514.5 1491.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="381" y="1310" width="260" height="120" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 242px; height: 1px; padding-top: 1370px; margin-left: 399px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">第二步:<span>签到表记录<br /><br /><div>用户Id</div><div>距离上次打卡相差天数:默认99999</div><div>是否补签:否</div><div><br /></div></span></div></div></div></foreignObject><text x="399" y="1374" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px">第二步:签到表记录用户Id...</text></switch></g><path d="M 1070 410 L 1070 453.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1070 458.88 L 1066.5 451.88 L 1070 453.63 L 1073.5 451.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 435px; margin-left: 1070px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">是</div></div></div></foreignObject><text x="1070" y="438" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">是</text></switch></g><path d="M 1180 345 L 1233.63 345" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1238.88 345 L 1231.88 348.5 L 1233.63 345 L 1231.88 341.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 345px; margin-left: 1210px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">否</div></div></div></foreignObject><text x="1210" y="348" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">否</text></switch></g><path d="M 1070 280 L 1180 345 L 1070 410 L 960 345 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 345px; margin-left: 961px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><br />判断“当天日期-2”数据是否为空<br />(即前天数据)</div></div></div></foreignObject><text x="1070" y="349" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">判断“当天日期-2”数据是否为空...</text></switch></g><path d="M 980 530 L 1000 460 L 1160 460 L 1140 530 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 495px; margin-left: 981px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">返回:2</div></div></div></foreignObject><text x="1070" y="499" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">返回:2</text></switch></g><path d="M 1350 410 L 1350 453.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1350 458.88 L 1346.5 451.88 L 1350 453.63 L 1353.5 451.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 435px; margin-left: 1350px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">是</div></div></div></foreignObject><text x="1350" y="438" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">是</text></switch></g><path d="M 1350 280 L 1460 345 L 1350 410 L 1240 345 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 345px; margin-left: 1241px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><br />判断“当天日期-3”数据是否为空<br />(即前天数据)</div></div></div></foreignObject><text x="1350" y="349" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">判断“当天日期-3”数据是否为空...</text></switch></g><path d="M 1260 530 L 1280 460 L 1440 460 L 1420 530 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 495px; margin-left: 1261px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">返回:3</div></div></div></foreignObject><text x="1350" y="499" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">返回:3</text></switch></g><path d="M 1073.18 60 L 1046.35 114.29" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1044.02 119 L 1043.99 111.17 L 1046.35 114.29 L 1050.26 114.27 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="1028" y="0" width="120" height="60" rx="9" ry="9" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 30px; margin-left: 1029px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">获取签到天数</div></div></div></foreignObject><text x="1088" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">获取签到天数</text></switch></g><path d="M 514.85 750 L 512.4 813.64" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 512.2 818.88 L 508.97 811.75 L 512.4 813.64 L 515.96 812.02 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 381 750 L 401 690 L 651 690 L 631 750 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 720px; margin-left: 382px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">【签到-积分添加】流程继续</div></div></div></foreignObject><text x="516" y="724" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">【签到-积分添加】流程继续</text></switch></g><path d="M 1294 750 L 1294 853.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 1294 858.88 L 1290.5 851.88 L 1294 853.63 L 1297.5 851.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 1159 750 L 1179 690 L 1429 690 L 1409 750 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 720px; margin-left: 1160px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">【获取签到天数】流程继续</div></div></div></foreignObject><text x="1294" y="724" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">【获取签到天数】流程继续</text></switch></g><rect x="1123" y="860" width="342" height="60" rx="9" ry="9" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 340px; height: 1px; padding-top: 890px; margin-left: 1124px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">接口直接返回该用户的签到天数</div></div></div></foreignObject><text x="1294" y="894" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">接口直接返回该用户的签到天数</text></switch></g><path d="M 1530 390 L 1530 360 L 1800 360 L 1800 390" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 1530 390 L 1530 470 L 1800 470 L 1800 390" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 1530 390 L 1800 390" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g fill="rgb(0, 0, 0)" font-family="Helvetica" pointer-events="none" text-anchor="middle" font-size="12px"><text x="1664.5" y="379.5">提示</text></g><g fill="rgb(0, 0, 0)" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-1534-390-262-80-0)" font-size="12px"><text x="1535.5" y="434.5">以此类推获取七天内的签到数据</text></g><rect x="340" y="1500" width="342" height="60" rx="9" ry="9" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 340px; height: 1px; padding-top: 1530px; margin-left: 341px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">接口返回:是否执行签到成功</div></div></div></foreignObject><text x="511" y="1534" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">接口返回:是否执行签到成功</text></switch></g><path d="M 511 880 L 511 963.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 511 968.88 L 507.5 961.88 L 511 963.63 L 514.5 961.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 376 880 L 396 820 L 646 820 L 626 880 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 850px; margin-left: 377px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">根据“返回天数”查询“签到天数的积分规则”</div></div></div></foreignObject><text x="511" y="854" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">根据“返回天数”查询“签到天数的积分规则”</text></switch></g><path d="M 550 350 L 623.63 350" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 628.88 350 L 621.88 353.5 L 623.63 350 L 621.88 346.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 350px; margin-left: 590px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;">否</div></div></div></foreignObject><text x="590" y="353" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">否</text></switch></g><path d="M 430 420 L 430 453.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><path d="M 430 458.88 L 426.5 451.88 L 430 453.63 L 433.5 451.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 440px; margin-left: 430px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; background-color: rgb(255, 255, 255); white-space: nowrap;">是</div></div></div></foreignObject><text x="430" y="443" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">是</text></switch></g><path d="M 430 280 L 550 350 L 430 420 L 310 350 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 238px; height: 1px; padding-top: 350px; margin-left: 311px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;"><br />判断数据是否为8条</div></div></div></foreignObject><text x="430" y="354" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
判断数据是否为8条</text></switch></g><path d="M 660 530 L 680 460 L 840 460 L 820 530 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 495px; margin-left: 661px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">返回:1</div></div></div></foreignObject><text x="750" y="499" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">返回:1</text></switch></g><path d="M 340 540 L 360 460 L 520 460 L 500 540 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 500px; margin-left: 341px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: none; white-space: normal; overflow-wrap: normal;">返回:1<br /><br />(因为程序是7天为一个周期<br />进行的签到,<br />第八天即为第一天)</div></div></div></foreignObject><text x="430" y="504" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">返回:1...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>

可将SVG代码放到此地址浏览 

https://www.runoob.com/try/try.php?filename=trysvg_myfirst

或 https://www.bejson.com/ui/svg_editor/

一、签到-数据库表设计

sql 代码

if exists (select 1
            from  sysindexes
           where  id    = object_id('QX_SignInLog')
            and   name  = 'Index_QX_SignInLog'
            and   indid > 0
            and   indid < 255)
   drop index QX_SignInLog.Index_QX_SignInLog
go

if exists (select 1
            from  sysobjects
           where  id = object_id('QX_SignInLog')
            and   type = 'U')
   drop table QX_SignInLog
go

/*==============================================================*/
/* Table: QX_SignInLog                                          */
/*==============================================================*/
create table QX_SignInLog (
   QX_SignInLogID       int                  identity,
   UserId               int                  null,
   DiscrepancyDay       int                  null default 99999,
   IsReplenish          bit                  null default 0,
   SignInTime           date                 null default getdate(),
   CreateTime           datetime             null default getdate(),
   UpdateTime           datetime             null,
   constraint PK_QX_SIGNINLOG primary key nonclustered (QX_SignInLogID)
)
go

if exists (select 1 from  sys.extended_properties
           where major_id = object_id('QX_SignInLog') and minor_id = 0)
begin 
   declare @CurrentUser sysname 
select @CurrentUser = user_name() 
execute sp_dropextendedproperty 'MS_Description',  
   'user', @CurrentUser, 'table', 'QX_SignInLog' 
 
end 


select @CurrentUser = user_name() 
execute sp_addextendedproperty 'MS_Description',  
   '用户签到记录表 QX_SignInLog', 
   'user', @CurrentUser, 'table', 'QX_SignInLog'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_SignInLog')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'QX_SignInLogID')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'QX_SignInLogID'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '用户签到记录ID',
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'QX_SignInLogID'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_SignInLog')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'UserId')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'UserId'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '用户Id',
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'UserId'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_SignInLog')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'DiscrepancyDay')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'DiscrepancyDay'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '距离上次打卡相差天数 默认99999',
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'DiscrepancyDay'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_SignInLog')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'IsReplenish')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'IsReplenish'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '是否补签',
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'IsReplenish'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_SignInLog')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'SignInTime')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'SignInTime'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '签到时间',
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'SignInTime'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_SignInLog')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'CreateTime')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'CreateTime'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '创建时间',
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'CreateTime'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_SignInLog')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'UpdateTime')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'UpdateTime'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '更新时间',
   'user', @CurrentUser, 'table', 'QX_SignInLog', 'column', 'UpdateTime'
go

/*==============================================================*/
/* Index: Index_QX_SignInLog                                    */
/*==============================================================*/
create unique index Index_QX_SignInLog on QX_SignInLog (
UserId ASC,
SignInTime ASC
)
go

二、签到加分规则

2.1数据库表设计

 

2.1.1 sql 积分模块分类QX_ScoreModule

if exists (select 1
            from  sysobjects
           where  id = object_id('QX_ScoreModule')
            and   type = 'U')
   drop table QX_ScoreModule
go

/*==============================================================*/
/* Table: QX_ScoreModule                                        */
/*==============================================================*/
create table QX_ScoreModule (
   ModuleCode           varchar(20)          collate Chinese_PRC_CI_AS not null,
   ModuleName           nvarchar(50)         collate Chinese_PRC_CI_AS not null,
   Description          nvarchar(200)        collate Chinese_PRC_CI_AS null,
   constraint PK_QX_SCOREMODULE primary key (ModuleCode)
)
go

if exists (select 1 from  sys.extended_properties
           where major_id = object_id('QX_ScoreModule') and minor_id = 0)
begin 
   declare @CurrentUser sysname 
select @CurrentUser = user_name() 
execute sp_dropextendedproperty 'MS_Description',  
   'user', @CurrentUser, 'table', 'QX_ScoreModule' 
 
end 


select @CurrentUser = user_name() 
execute sp_addextendedproperty 'MS_Description',  
   '积分模块分类QX_ScoreModule', 
   'user', @CurrentUser, 'table', 'QX_ScoreModule'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_ScoreModule')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'ModuleCode')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_ScoreModule', 'column', 'ModuleCode'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '所属模块编号',
   'user', @CurrentUser, 'table', 'QX_ScoreModule', 'column', 'ModuleCode'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_ScoreModule')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'ModuleName')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_ScoreModule', 'column', 'ModuleName'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '所属模块',
   'user', @CurrentUser, 'table', 'QX_ScoreModule', 'column', 'ModuleName'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_ScoreModule')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'Description')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_ScoreModule', 'column', 'Description'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '说明',
   'user', @CurrentUser, 'table', 'QX_ScoreModule', 'column', 'Description'
go

2.1.2 sql 积分规则设置QX_Member_ScoreSetting

if exists (select 1
            from  sysobjects
           where  id = object_id('dbo.QX_Member_ScoreSetting')
            and   type = 'U')
   drop table dbo.QX_Member_ScoreSetting
go

/*==============================================================*/
/* Table: QX_Member_ScoreSetting                                */
/*==============================================================*/
create table dbo.QX_Member_ScoreSetting (
   ActionId             int                  identity(1, 1) not for replication,
   ActionCode           varchar(20)          collate Chinese_PRC_CI_AS null,
   ActionName           nvarchar(50)         collate Chinese_PRC_CI_AS null,
   ModuleName           nvarchar(50)         collate Chinese_PRC_CI_AS null,
   ModuleCode           varchar(20)          collate Chinese_PRC_CI_AS null,
   Score                decimal              null constraint DF_QX_Member_ScoreSetting_Score default (0),
   Description          nvarchar(200)        collate Chinese_PRC_CI_AS null,
   AvailablePeriod      tinyint              null,
   IsAddOnly            bit                  null default 1,
   Limit                int                  null,
   IsTask               bit                  null default 0,
   IconUrl              varchar(200)         null,
   CreateTime           datetime             null default getdate(),
   CreateUserId         int                  null,
   UpdateTime           datetime             null,
   UpdateUserId         int                  null,
   IsDelete             bit                  not null default 0,
   DeleteTime           datetime             null,
   DeleteUserId         int                  null,
   constraint PK_QX_Member_ScoreSetting primary key (ActionId)
         on "PRIMARY"
)
on "PRIMARY"
go

if exists (select 1 from  sys.extended_properties
           where major_id = object_id('dbo.QX_Member_ScoreSetting') and minor_id = 0)
begin 
   execute sp_dropextendedproperty 'MS_Description',  
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting' 
 
end 


execute sp_addextendedproperty 'MS_Description',  
   '积分规则QX_Member_ScoreSetting
   
   AvailablePeriod
   积分可用周期:0不限,1一年,2二年
   
   IsAddOnly
   是否只增加一次:例如用户注册只增加一次', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'ActionId')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'ActionId'

end


execute sp_addextendedproperty 'MS_Description', 
   '动作ID',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'ActionId'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'ActionCode')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'ActionCode'

end


execute sp_addextendedproperty 'MS_Description', 
   '动作编号',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'ActionCode'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'ActionName')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'ActionName'

end


execute sp_addextendedproperty 'MS_Description', 
   '动作名称',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'ActionName'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'ModuleName')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'ModuleName'

end


execute sp_addextendedproperty 'MS_Description', 
   '所属模块',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'ModuleName'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'ModuleCode')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'ModuleCode'

end


execute sp_addextendedproperty 'MS_Description', 
   '所属模块编号',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'ModuleCode'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'Score')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'Score'

end


execute sp_addextendedproperty 'MS_Description', 
   '单次增加积分 ',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'Score'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'Description')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'Description'

end


execute sp_addextendedproperty 'MS_Description', 
   '说明',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'Description'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'AvailablePeriod')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'AvailablePeriod'

end


execute sp_addextendedproperty 'MS_Description', 
   '积分可用周期:0不限,1一年,2二年',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'AvailablePeriod'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'IsAddOnly')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'IsAddOnly'

end


execute sp_addextendedproperty 'MS_Description', 
   '是否只增加一次:例如用户注册只增加一次',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'IsAddOnly'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'Limit')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'Limit'

end


execute sp_addextendedproperty 'MS_Description', 
   '每天最大增加次数',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'Limit'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'IsTask')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'IsTask'

end


execute sp_addextendedproperty 'MS_Description', 
   '是否任务',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'IsTask'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'IconUrl')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'IconUrl'

end


execute sp_addextendedproperty 'MS_Description', 
   '图标',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'IconUrl'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'CreateTime')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'CreateTime'

end


execute sp_addextendedproperty 'MS_Description', 
   '创建时间',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'CreateTime'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'CreateUserId')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'CreateUserId'

end


execute sp_addextendedproperty 'MS_Description', 
   '创建人ID',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'CreateUserId'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'UpdateTime')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'UpdateTime'

end


execute sp_addextendedproperty 'MS_Description', 
   '更新时间',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'UpdateTime'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'UpdateUserId')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'UpdateUserId'

end


execute sp_addextendedproperty 'MS_Description', 
   '更新人ID',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'UpdateUserId'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'IsDelete')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'IsDelete'

end


execute sp_addextendedproperty 'MS_Description', 
   '是否删除 0=未删除,1=已删除,默认为0',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'IsDelete'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'DeleteTime')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'DeleteTime'

end


execute sp_addextendedproperty 'MS_Description', 
   '删除时间',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'DeleteTime'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('dbo.QX_Member_ScoreSetting')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'DeleteUserId')
)
begin
   execute sp_dropextendedproperty 'MS_Description', 
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'DeleteUserId'

end


execute sp_addextendedproperty 'MS_Description', 
   '删除人ID',
   'user', 'dbo', 'table', 'QX_Member_ScoreSetting', 'column', 'DeleteUserId'
go

2.1.3 sql 积分规则设置QX_Member_ScoreSetting

 

if exists (select 1
            from  sysobjects
           where  id = object_id('QX_Score_TradeDetails')
            and   type = 'U')
   drop table QX_Score_TradeDetails
go

/*==============================================================*/
/* Table: QX_Score_TradeDetails                                 */
/*==============================================================*/
create table QX_Score_TradeDetails (
   ID                   int                  identity,
   UserId               int                  null,
   BeforeScore          int                  null,
   TradeScore           int                  null,
   AfterScore           int                  null,
   TradeType            int                  null,
   TradeTime            datetime             null,
   TradeTitle           nvarchar(50)         null,
   TradeDescription     nvarchar(100)        null,
   SourceSystemCode     int                  null,
   IsPermanentScore     bit                  not null default 0,
   ExpirationTime       datetime             null,
   ScoreActionId        int                  null,
   Column_14            char(10)             null,
   constraint PK_QX_SCORE_TRADEDETAILS primary key (ID)
)
go

if exists (select 1 from  sys.extended_properties
           where major_id = object_id('QX_Score_TradeDetails') and minor_id = 0)
begin 
   declare @CurrentUser sysname 
select @CurrentUser = user_name() 
execute sp_dropextendedproperty 'MS_Description',  
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails' 
 
end 


select @CurrentUser = user_name() 
execute sp_addextendedproperty 'MS_Description',  
   '积分交易流水表 QX_Score_TradeDetails
   
   积分规则ID :ScoreActionId 对应QX_Member_ScoreSetting表', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_Score_TradeDetails')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'ID')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'ID'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '表ID',
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'ID'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_Score_TradeDetails')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'UserId')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'UserId'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '用户ID',
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'UserId'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_Score_TradeDetails')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'BeforeScore')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'BeforeScore'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '交易前积分',
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'BeforeScore'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_Score_TradeDetails')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'TradeScore')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'TradeScore'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '交易积分',
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'TradeScore'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_Score_TradeDetails')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'AfterScore')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'AfterScore'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '交易后积分',
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'AfterScore'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_Score_TradeDetails')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'TradeType')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'TradeType'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '积分交易类型 0=增加,1=扣减',
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'TradeType'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_Score_TradeDetails')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'TradeTime')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'TradeTime'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '交易时间',
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'TradeTime'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_Score_TradeDetails')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'TradeTitle')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'TradeTitle'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '积分交易标题',
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'TradeTitle'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_Score_TradeDetails')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'TradeDescription')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'TradeDescription'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '积分交易描述',
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'TradeDescription'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_Score_TradeDetails')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'SourceSystemCode')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'SourceSystemCode'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '积分交易渠道,详细见《积分交易渠道代码表》',
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'SourceSystemCode'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_Score_TradeDetails')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'IsPermanentScore')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'IsPermanentScore'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '是否永久积分 0=非永久,1=永久积分',
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'IsPermanentScore'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_Score_TradeDetails')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'ExpirationTime')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'ExpirationTime'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '积分到期时间',
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'ExpirationTime'
go

if exists(select 1 from sys.extended_properties p where
      p.major_id = object_id('QX_Score_TradeDetails')
  and p.minor_id = (select c.column_id from sys.columns c where c.object_id = p.major_id and c.name = 'ScoreActionId')
)
begin
   declare @CurrentUser sysname
select @CurrentUser = user_name()
execute sp_dropextendedproperty 'MS_Description', 
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'ScoreActionId'

end


select @CurrentUser = user_name()
execute sp_addextendedproperty 'MS_Description', 
   '积分规则ID;对应QX_Member_ScoreSetting表',
   'user', @CurrentUser, 'table', 'QX_Score_TradeDetails', 'column', 'ScoreActionId'
go

 2.2积分规则效果图

 

 

 三、签到工厂

3.1模型代码

    /// <summary>
    /// 签到数据
    /// </summary>
    public class SignInModel
    {
        /// <summary>
        /// 周期内连续签到总天数
        /// </summary>
        public int CountDays { set; get; } = 0;
        /// <summary>
        /// 第几天签到
        /// </summary>
        public int Day { set; get; } =1;
    }
 /// <summary>
    /// 用户签到记录表 QX_SignInLog
    /// </summary>
    public class QX_SignInLogModel
    {
        /// <summary>
        /// 用户签到记录ID
        /// </summary>		

        public int QX_SignInLogID
        {
            get { return _qx_signinlogid; }
            set { _qx_signinlogid = value; }
        }
        private int _qx_signinlogid;
        /// <summary>
        /// 用户Id
        /// </summary>		

        public int UserId
        {
            get { return _userid; }
            set { _userid = value; }
        }
        private int _userid;
        /// <summary>
        /// 距离上次打卡相差天数 默认99999
        /// </summary>		

        public int DiscrepancyDay
        {
            get { return _discrepancyday; }
            set { _discrepancyday = value; }
        }
        private int _discrepancyday=99999;
        /// <summary>
        /// 是否补签
        /// </summary>		

        public bool IsReplenish
        {
            get { return _isreplenish; }
            set { _isreplenish = value; }
        }
        private bool _isreplenish;
        /// <summary>
        /// 签到时间
        /// </summary>		

        public DateTime SignInTime
        {
            get { return _signintime; }
            set { _signintime = value; }
        }
        private DateTime _signintime;
        /// <summary>
        /// 创建时间
        /// </summary>		

        public DateTime CreateTime
        {
            get { return _createtime; }
            set { _createtime = value; }
        }
        private DateTime _createtime;
        /// <summary>
        /// 更新时间
        /// </summary>		

        public DateTime UpdateTime
        {
            get { return _updatetime; }
            set { _updatetime = value; }
        }
        private DateTime _updatetime;

    }

3.2 获取用户签到天数

 /// <summary>
        /// 获取用户签到天数
        /// </summary>
        /// <param name="UserId">用户ID</param>
        /// <param name="CycleDays">周期天数;例如:签到7天为一个周期</param>
        /// <param name="CurrentDate">当前日期</param>
        /// <returns></returns>
        public static SignInModel GetUserSignInDay(int UserId, int CycleDays, DateTime CurrentDate)
        {
            SignInModel result = new SignInModel();
            CycleDays = CycleDays + 1;//比当前周期天数多1天的日期,即第8天即为第1天
            DateTime StartDate = CurrentDate.AddDays(int.Parse("-" + CycleDays)).Date;
            DateTime EndDate = CurrentDate.AddHours(23).AddMinutes(59).AddSeconds(59); //当天最大时间

            try
            {
                List<QX_SignInLogModel> list = QX_SignInLogBLL.GetList(
              where: "UserId=@UserId and SignInTime>=@StartDate and SignInTime<=@EndDate",
              param: new { UserId, StartDate, EndDate },
              returnFields: "",
              orderby: "QX_SignInLogID desc"
              );
                //判断数据是否为空
                if (list != null || list.Count() > 0)
                {
                    //判断数据条数是否等于周期天数+1,如果是则重新开始为第1天
                    if (list.Count() < CycleDays)
                    {
                        CycleDays = CycleDays - 1;//上面对周期天数+1,现在重新减去

                        for (int i = 1; i <=CycleDays; i++)
                        {
                            DateTime itemStartDate = CurrentDate.AddDays(int.Parse("-" + i)).Date;//当前日期-i,如i=1即昨天日期
                              
                            List<QX_SignInLogModel> _list = list.Where(d=>d.SignInTime== itemStartDate).ToList();

                            if (_list == null || _list.Count()==0)
                            {
                                result.CountDays = i-1;
                                result.Day = i;
                                return result;
                            }

                        }
                    }
                    else {
                        result.CountDays = list.Count();
                        result.Day = 1;
                        return result;
                    }

                }
                else
                {
                    result.CountDays =0;
                    result.Day = 1;
                    return result;
                }
            }
            catch (Exception e)
            { 
                log.Error(e.LogErrorTxt()); 
            }


            return result;
        }

四、积分增减工厂

4.1工厂全部代码

 #region  积分工厂  

    /// <summary>
    /// 积分工厂
    /// </summary>
    public class ScoreFactory
    {
        private static Log log = LogFactory.GetLogger(typeof(ScoreFactory));

        /// <summary>
        /// 从缓存中获取积分规则
        /// </summary>
        private static List<QX_Member_ScoreSettingModel> ScoreSettingList = null;
        /// <summary>
        /// 根据积分规则“编号”获取对应积分规则
        /// </summary>
        private static QX_Member_ScoreSettingModel ScoreSettingModel = null;

        /// <summary>
        /// 用户当前积分规则下的积分记录
        /// </summary>
        private static List<ScoreTrade_Model> UserAll_ScoreTradeDetailsList = null;

        /// <summary>
        /// 获取用户当天积分规则下的积分数据
        /// </summary>
        private static List<ScoreTrade_Model> UserTodayAll_ScoreTradeDetailsList = null;

        /// <summary>
        /// 积分增减业务工厂
        /// </summary>
        public static ReturnResult ManageFactory(ScoreFactoryModel model)
        {
            ReturnResult result = new ReturnResult() { code = ((int)ResultCodeEnum.失败).ToString(), msg = "失败" };

            bool isExecute = false; //是否执行积分操作

            try
            { 
                //1.从缓存中获取积分规则
                ScoreSettingList = ScoreRegulationBLL.GetScoreRegulationList();

                //2.根据积分规则“编号”获取对应积分规则
                ScoreSettingModel = ScoreSettingList.Where(s => s.ActionCode == model.ActionCode).SingleOrDefault();

                




                //3.根据第2步的结果,判断积分是否为空 
                if (ScoreSettingModel == null)
                {
                    result.code = ((int)ResultCodeEnum.失败).ToString();
                    result.msg = "积分编号错误";
                    return result;
                }

                if (model.Score!= ScoreSettingModel.Score)
                {
                    result.code = ((int)ResultCodeEnum.失败).ToString();
                    result.msg = "积分分数不一致";
                    return result;
                }

                //3.2如果是签到 ScoreSettingModel.ModuleCode== "14"
                if (ScoreSettingModel.ModuleCode == "14")
                {
                    bool SignInStatus = false;
                    SignInModel signInModel = SignInFactory.GetUserSignInDay(model.UserId, 7, DateTime.Now.Date);

                    switch (signInModel.Day)
                    {
                        case 1:
                            SignInStatus = (ScoreSettingModel.ActionCode== "14001"); 
                            break;
                        case 2:
                            SignInStatus = (ScoreSettingModel.ActionCode == "14002");
                            break;
                        case 3:
                            SignInStatus = (ScoreSettingModel.ActionCode == "14003");
                            break;
                        case 4:
                            SignInStatus = (ScoreSettingModel.ActionCode == "14004");
                            break;
                        case 5:
                            SignInStatus = (ScoreSettingModel.ActionCode == "14005");
                            break;
                        case 6:
                            SignInStatus = (ScoreSettingModel.ActionCode == "14006");
                            break;
                        case 7:
                            SignInStatus = (ScoreSettingModel.ActionCode == "14007");
                            break;
                        default:
                            SignInStatus = false;
                            break;
                    }

                    if (SignInStatus== false)
                    {
                        result.code = ((int)ResultCodeEnum.失败).ToString();
                        result.msg = "签到传参错误";
                        return result;
                    }
                }

                //根据用户ID和积分编号查找积分记录
                UserAll_ScoreTradeDetailsList = QX_Score_TradeDetailsBLL.GetList(
                where: "UserId=@UserId and ScoreActionId=@ScoreActionId",
                param: new { UserId = model.UserId, ScoreActionId = ScoreSettingModel.ActionId },
                returnFields: "",
                orderby: "id desc"
                );

                //4.判断是否只增加一次  字段:IsAddOnly
                if (ScoreSettingModel.IsAddOnly == true && UserAll_ScoreTradeDetailsList.Count == 0)
                {
                    isExecute = true; //是否执行积分操作  
                }
                else
                {
                    isExecute = false; //是否执行积分操作  
                }


                //5.如果满足第4步骤,则不判断每天最大增加次数 
                if (isExecute == false)
                {
                    //获取当天的开始时间
                    DateTime TodayStart = DateTime.Today; //当天最小时间
                    DateTime TodayEnd = TodayStart.AddHours(23).AddMinutes(59).AddSeconds(59); //当天最大时间

                    //获取用户当天积分规则下的积分数据
                    UserTodayAll_ScoreTradeDetailsList = UserAll_ScoreTradeDetailsList.Where(s => s.TradeTime >= TodayStart && s.TradeTime <= TodayEnd).ToList();

                    //5.2.判断每天最大增加次数  字段:Limit
                    if (UserTodayAll_ScoreTradeDetailsList.Count < ScoreSettingModel.Limit)
                    {
                        isExecute = true; //是否执行积分操作  
                    }
                    else
                    {
                        isExecute = false; //是否执行积分操作  
                    }
                }



                #region 6.增加积分/给用户发送一条消息
                if (isExecute == true)
                {
                    #region 6.1增加积分  
                    ScoreBusiness scoreBusiness = new ScoreBusiness(new Token() { UserId = model.UserId.ToString() });
                    ScoreTrade_Model scoreTrade_Model = new ScoreTrade_Model();
                    scoreTrade_Model.ScoreActionId = ScoreSettingModel.ActionId;
                    scoreTrade_Model.TradeScore = (int)ScoreSettingModel.Score;
                    scoreTrade_Model.TradeType = scoreTrade_Model.TradeScore > 0 ? 0 : 1;
                    scoreTrade_Model.TradeTitle = model.Title;
                    scoreTrade_Model.TradeDescription = model.Content;
                    scoreTrade_Model.SourceSystemCode = model.SourceSystemCode;
                    scoreTrade_Model.IsPermanentScore = ScoreSettingModel.AvailablePeriod == 0 ? 1 : 0;
                    //如果积分是非永久积分则加上到期时间
                    if (scoreTrade_Model.IsPermanentScore == 0)
                    {
                        scoreTrade_Model.ExpirationTime = DateTime.Now.AddYears(ScoreSettingModel.AvailablePeriod);
                    }
                    result = scoreBusiness.SetScoreTrade(scoreTrade_Model);
                    #endregion

                    //如果积分添加不成功则不执行发送消息
                    if (result.code == ((int)ResultCodeEnum.成功).ToString())
                    {
                        #region 6.2给用户发送一条消息
                        string msgStr = "[" + ScoreSettingModel.ActionName + "]" + "积分" + (ScoreSettingModel.Score >= 0 ? "+" : "-") + ScoreSettingModel.Score;
                        Message_NotificationBLL message_NotificationBLL = new Message_NotificationBLL();
                        int msg_res = message_NotificationBLL.SendNotifyMsgToMember(
                             Title: msgStr,
                             Content: msgStr,
                             Action_UserId: null,
                             Action_NickName: "系统",
                             Receive_UserId: model.UserId,
                             IsJump: false,
                             JumpObjectID: 0,
                             JumpObjectType: -1,
                             Message_Type: 0,
                             JumpObjectTitle: ""
                             );
                        #endregion

                        if (result.code == ((int)ResultCodeEnum.成功).ToString() && msg_res >= 0)
                        {
                            #region 6.3 如果是签到规则,则增加一条签到记录
                            if (ScoreSettingModel.ModuleCode== "14")
                            {
                                int SignInLogStatus = QX_SignInLogBLL.Add(new QX_SignInLogModel() {
                                    UserId = model.UserId,
                                    SignInTime = DateTime.Now.Date,
                                    IsReplenish = false
                              });
                                if (SignInLogStatus > 0)
                                {
                                    result.code = ((int)ResultCodeEnum.成功).ToString();
                                    result.msg = "成功";
                                }
                                else {
                                    log.Error("【增加一条签到记录】异常 SignInLogStatus:" + SignInLogStatus + "【执行积分增加状态】code:" + result.code + " msg:" + result.msg + " 【执行给用户发送一条消息状态】响应行数:" + msg_res);
                                }
                            }
                            #endregion 
                        }
                        else
                        {
                            log.Error("【执行积分增加状态】code:" + result.code + " msg:" + result.msg + " 【执行给用户发送一条消息状态】响应行数:" + msg_res);
                        }
                    }
                    else
                    {
                        log.Error("【执行积分增加状态】code:" + result.code + " msg:" + result.msg);
                    }
                }
                else { 
                    result.code = ((int)ResultCodeEnum.失败).ToString();
                    result.msg = "积分增加达到规则上限";
                }
                #endregion

            }
            catch (Exception e)
            {
                result.msg = "异常";
                result.code = ((int)ResultCodeEnum.异常).ToString();
                log.Error(e.LogErrorTxt());
            }
            return result;
        }

        /// <summary>
        /// 检查-积分工厂数据字段是否为空
        /// </summary>
        /// <param name="model">积分工厂数据模型</param>
        /// <returns></returns>
        public static ReturnResult ScoreFactoryModelChack(ScoreFactoryModel model)
        {
            ReturnResult result = new ReturnResult() { code = "", msg = "" };
            if (model.UserId < 1)
            {
                result.code = ((int)ResultCodeEnum.失败).ToString();
                result.msg = "请检查传参id";
            }
            else if (model.ActionCode.Length < 1)
            {
                result.code = ((int)ResultCodeEnum.失败).ToString();
                result.msg = "请检查传参ActionCode";
            } 
            else if (model.Title.Length < 1)
            {
                result.code = ((int)ResultCodeEnum.失败).ToString();
                result.msg = "请检查传参Title";
            }
            else if (model.Content.Length < 1)
            {
                result.code = ((int)ResultCodeEnum.失败).ToString();
                result.msg = "请检查传参Content";
            }
            else if (model.SourceSystemCode < 1)
            {
                result.code = ((int)ResultCodeEnum.失败).ToString();
                result.msg = "请检查传参SourceSystemCode";
            }
            else {
                result.code = ((int)ResultCodeEnum.成功).ToString();
                result.msg = "验证通过";
            }
            return result;
        }
    }

    /// <summary>
    /// 积分工厂数据模型
    /// </summary>
    public class ScoreFactoryModel
    {
        /// <summary>
        /// 用户ID
        /// </summary>
        public int UserId { set; get; }

        /// <summary>
        /// 积分-动作编号
        /// </summary>	
        public string ActionCode { set; get; }

        /// <summary>
        /// 积分
        /// </summary>
        public decimal Score { set; get; }

        /// <summary>
        /// 标题:在什么场景下的积分操作;不得超过50个字
        /// </summary>
        public string Title { set; get; }

        /// <summary>
        /// 内容描述:在什么场景下的积分操作描述;不得超过100个字
        /// </summary>
        public string Content { set; get; }

        /// <summary>
        /// 积分来源系统代码-平台代码
        /// </summary>
        public int SourceSystemCode { set; get; }
    }
    #endregion

4.2工厂用到的模型

/// <summary>
    /// 积分规则设置模型
    /// </summary>
    public class QX_Member_ScoreSettingModel
    {

        /// <summary>
        /// 动作ID
        /// </summary>		
        public int ActionId { get; set; }
        /// <summary>
        /// 动作编号
        /// </summary>		
        public string ActionCode
        {
            get { return _ActionCode; }
            set { _ActionCode = value.Trim(); }
        }
        private string _ActionCode;
        /// <summary>
        /// 动作名称
        /// </summary>		
        public string ActionName {
            get { return _ActionName; }
            set { _ActionName = value.Trim(); }
        }
        private string _ActionName;
        /// <summary>
        /// 所属模块
        /// </summary>		
        public string ModuleName {
            get { return _ModuleName; }
            set { _ModuleName = value.Trim(); }
        }
        private string _ModuleName;
        /// <summary>
        /// 所属模块编号
        /// </summary>		
        public string ModuleCode {
            get { return _ModuleCode; }
            set { _ModuleCode = value.Trim(); }
        }
        private string _ModuleCode;
        /// <summary>
        /// 积分(大于0表示增加,小于0表示扣分)
        /// </summary>		
        public decimal Score { get; set; } =1;
        /// <summary>
        /// 说明
        /// </summary>		
        public string Description { get; set; }
        /// <summary>
        /// 积分可用周期 0:不限制
        /// </summary>		
        public int AvailablePeriod { get; set; } = 0;
        /// <summary>
        /// 是否只增加一次
        /// </summary>		
        public bool IsAddOnly { get; set; } = false;
        /// <summary>
        /// 每天最大增加次数
        /// </summary>		
        public int Limit { get; set; } = 1;
        /// <summary>
        /// 创建时间
        /// </summary>		
        public DateTime CreateTime { get; set; }
        /// <summary>
        /// 创建人ID
        /// </summary>		
        public int CreateUserId { get; set; }
        /// <summary>
        /// 更新时间
        /// </summary>		
        public DateTime UpdateTime { get; set; }
        /// <summary>
        /// 更新人ID
        /// </summary>		
        public int UpdateUserId { get; set; }
        /// <summary>
        /// 是否删除
        /// </summary>		
        public bool IsDelete { get; set; }
        /// <summary>
        /// 删除时间
        /// </summary>		
        public DateTime DeleteTime { get; set; }
        /// <summary>
        /// 删除人ID
        /// </summary>		
        public int DeleteUserId { get; set; }

        /// <summary>
        /// 是否任务
        /// </summary>		
        public bool IsTask { get; set; } = false;
        /// <summary>
        /// 图标
        /// </summary>
        public string IconUrl { get; set; }
    }
  public  class ScoreTrade_Model
    {
        /// <summary>
        /// 交易积分
        /// </summary>
        public int TradeScore { get; set; }

        /// <summary>
        /// 交易类型 0=增加积分,1=扣减积分
        /// </summary>
        public int TradeType { get; set; }
        /// <summary>
        /// 交易标题限50字
        /// </summary>
        public string TradeTitle { get; set; }
        /// <summary>
        /// 交易描述限100字
        /// </summary>
        public string TradeDescription { get; set; }

        /// <summary>
        /// 积分来源系统代码
        /// </summary>
        public int SourceSystemCode { get; set; }

        /// <summary>
        /// 是否永久积分 0=非永久,1=永久积分
        /// </summary>
        public int IsPermanentScore { get; set; }

        /// <summary>
        /// 积分到期时间(可为空),无到期时间则为永久积分
        /// </summary>
        public  DateTime? ExpirationTime { get; set; }

        /// <summary>
        /// 交易时间
        /// </summary>
        public DateTime TradeTime { get; set; }

        /// <summary>
        /// 积分规则ID ;(默认值:88888是系统增加的积分,未通过积分规则)该字段对应QX_Member_ScoreSetting表
        /// </summary>
        public int ScoreActionId { get; set; } = 88888;

    }
    /// <summary>
    /// 返回结果
    /// </summary>
    public class ReturnResult
    {
        /// <summary>
        /// 执行是否成功
        /// </summary>
        public string code { get; set; }

        /// <summary>
        /// 返回信息
        /// </summary>
        public string msg { get; set; }


        /// <summary>
        /// 备用数据
        /// </summary>
        public object data { get; set; }
    }

五、积分规则缓存

因为“积分规则”经常使用,所以需要将规则缓存

5.1缓存帮助类

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Caching;

namespace Common
{
   public  class CacheExtend
    {
        /// <summary>
        /// 设置缓存时间,配置(从配置文件中读取)
        /// </summary>
        private static  double Seconds =Convert.ToDouble(Configs.GetValue("CacheTimeout"));

        /// <summary>
        /// 缓存指定对象,设置缓存
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">值</param>
        /// <param name="OutTime">超时时间; 单位:秒</param>
        /// <returns></returns>
        public static bool Set(string key, object value, double OutTime =0)
        {
            if (OutTime == 0)
            {
                return Set(key, value, null, DateTime.Now.AddSeconds(Seconds), Cache.NoSlidingExpiration,CacheItemPriority.Default, null);
            }
            else {
                return Set(key, value, null, DateTime.Now.AddSeconds(OutTime), Cache.NoSlidingExpiration, CacheItemPriority.Default, null); 
            }
          
        }

        /// <summary>
        /// 缓存指定对象,设置缓存
        /// </summary>
        public static bool Set(string key, object value, string path)
        {
            try
            {
                var cacheDependency = new CacheDependency(path);
                return Set(key, value, cacheDependency);
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 缓存指定对象,设置缓存
        /// </summary>
        public static bool Set(string key, object value, CacheDependency cacheDependency)
        {
            return Set(key, value, cacheDependency, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration,
            CacheItemPriority.Default, null);
        }

        /// <summary>
        /// 缓存指定对象,设置缓存
        /// </summary>
        public static bool Set(string key, object value, double seconds, bool isAbsulute)
        {
            return Set(key, value, null, (isAbsulute ? DateTime.Now.AddSeconds(seconds) : Cache.NoAbsoluteExpiration),
            (isAbsulute ? Cache.NoSlidingExpiration : TimeSpan.FromSeconds(seconds)), CacheItemPriority.Default,
            null);
        }

        /// <summary>
        /// 获取缓存对象
        /// </summary>
        public static object Get(string key)
        {
            return GetPrivate(key);
        }

        /// <summary>
        /// 判断缓存中是否含有缓存该键
        /// </summary>
        public static bool Exists(string key)
        {
            return (GetPrivate(key) != null);
        }

        /// <summary>
        /// 移除缓存对象
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool Remove(string key)
        {
            if (string.IsNullOrEmpty(key))
            {
                return false;
            }
            HttpRuntime.Cache.Remove(key);
            return true;
        }

        /// <summary>
        /// 移除所有缓存
        /// </summary>
        /// <returns></returns>
        public static bool RemoveAll()
        {
            IDictionaryEnumerator iDictionaryEnumerator = HttpRuntime.Cache.GetEnumerator();
            while (iDictionaryEnumerator.MoveNext())
            {
                HttpRuntime.Cache.Remove(Convert.ToString(iDictionaryEnumerator.Key));
            }
            return true;
        }


        /// <summary>
        /// 尝试获取缓存,不存在则执行匿名委托
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static T TryGet<T>(string key, Func<T> func)
        {
            if (Exists(key)) return (T)Get(key);
            var result = func.Invoke();
            Set(key, result);
            return result;
        }


        /// <summary>
        /// 设置缓存
        /// </summary>
        public static bool Set(string key, object value, CacheDependency cacheDependency, DateTime dateTime,
        TimeSpan timeSpan, CacheItemPriority cacheItemPriority, CacheItemRemovedCallback cacheItemRemovedCallback)
        {
            if (string.IsNullOrEmpty(key) || value == null)
            {
                return false;
            }
            HttpRuntime.Cache.Insert(key, value, cacheDependency, dateTime, timeSpan, cacheItemPriority,
            cacheItemRemovedCallback);
            return true;
        }

        /// <summary>
        /// 获取缓存
        /// </summary>
        private static object GetPrivate(string key)
        {
            return string.IsNullOrEmpty(key) ? null : HttpRuntime.Cache.Get(key);
        }

    }
}

5.2 积分规则缓存业务中间层

 /// <summary>
    /// 积分规则-业务中间层,专门处理积分缓存数据
    /// </summary>
   public class ScoreRegulationBLL
    {
       private static  string ScoreRegulationKey="ScoreRegulation"; 

        /// <summary>
        /// 获取“积分规则”-该方法走的是缓存
        /// </summary>
        /// <returns></returns>
        public static List<QX_Member_ScoreSettingModel> GetScoreRegulationList()
        {
            List<QX_Member_ScoreSettingModel> result = null;

            if (CacheExtend.Exists(ScoreRegulationKey))
            {
                result = (List<QX_Member_ScoreSettingModel>)CacheExtend.Get(ScoreRegulationKey);
            }
            else { 

                #region 直接数据库获取 2022-2-16修改
                result = QX_Member_ScoreSettingBLL.GetList();
                CacheExtend.Set(ScoreRegulationKey, result);
                #endregion 
            }

            return result;

        }
        /// <summary>
        /// 清除“积分规则”缓存
        /// </summary>
        /// <returns>false:无数据 true:数据已清除</returns>
        public static bool RemoveScoreRegulation() {
            bool result = false;
            if (CacheExtend.Exists(ScoreRegulationKey))
            {
                result = CacheExtend.Remove(ScoreRegulationKey);
            }
            else {
                result = true;
            }
            return result;
        }
    }

六、增加积分逻辑中间层

6.1 Token 逻辑中间层

  public class Token
    { 
        /// <summary>
        /// 用户id
        /// </summary>
        public string UserId { get; set; }
        /// <summary>
        /// 登录时间  ,PC端登录 有过期时间,移动端登录 不判断过期时间
        /// </summary>
        public DateTime LoginTime { get; set; }

        /*
         *核心解密代码不展示
        */
    }

6.2 用户账户积分管理方法(加、减积分方法)

/// <summary>
/// 积分业务处理类 - 中间层
/// </summary>
public class ScoreBusiness
{
	public Token token = new Token();
	
	public ScoreBusiness(Token _token) {
	token = _token;
	}
	
	#region   用户账户积分管理方法(加、减积分方法) 2021-7-16
        /// <summary>
        /// 积分交易(加、减积分接口)
        /// </summary>
        /// <returns></returns> 
        public ReturnResult SetScoreTrade(ScoreTrade_Model model)
        {
            bool paramVerify = true;
            ReturnResult result = new ReturnResult() { code = "", msg = "" };

            if (model.ScoreActionId<=0)
            {
                result.code = ((int)ResultCodeEnum.失败).ToString();
                result.msg = "积分规则ID 无效";
                return result;
            }

            try
            {
                #region 参数校验
                if (model == null)
                {
                    paramVerify = false;
                    result.code = ((int)ResultCodeEnum.失败).ToString();
                    result.msg = "缺少必须的参数!";
                    return result;
                }

                if (model.TradeScore <= 0)
                {
                    paramVerify = false;
                    result.code = ((int)ResultCodeEnum.失败).ToString();
                    result.msg = "交易积分必须大于0!";
                    return result;
                }

                if (!RegexCheck.IsNUM_CustomRange(model.TradeType.ToString(), 0, 1))
                {
                    paramVerify = false;
                    result.code = ((int)ResultCodeEnum.失败).ToString();
                    result.msg = "交易类型不合法!";
                    return result;
                }
                else
                {
                    //如果交易类型是扣减则判断用户账户积分是否满足被扣减的余额
                    if (model.TradeType == 1)
                    {
                        //步骤2.查询用户账号积分余额判断余额是否满足兑换条件 (本次兑换所需积分=产品所需积分*兑换数量)
                        var MemberModel = sqlbase.GetModel<User_table>("User_table", "Score", "UserId=" + token.UserId);
                        if (MemberModel.Score < model.TradeScore)
                        {
                            paramVerify = false;
                            result.code = ((int)ResultCodeEnum.失败).ToString();
                            result.msg = "账户积分不满足扣减积分!";
                            return result;
                        }
                    }
                }


                if (string.IsNullOrWhiteSpace(model.TradeTitle))
                {
                    paramVerify = false;
                    result.code = ((int)ResultCodeEnum.失败).ToString();
                    result.msg = "交易标题不能为空!";
                    return result;
                }


                if (model.SourceSystemCode <= 0)
                {
                    paramVerify = false;
                    result.code = ((int)ResultCodeEnum.失败).ToString();
                    result.msg = "交易渠道代码不正确!";
                    return result;
                }
                else
                {
                    var sourceSystem = sqlbase.GetModel<QX_SourceSystemEntity>("QX_SourceSystem", "SourceSystemCode", "SourceSystemCode=" + model.SourceSystemCode);
                    if (sourceSystem == null)
                    {
                        paramVerify = false;
                        result.code = ((int)ResultCodeEnum.失败).ToString();
                        result.msg = "交易渠道代码不正确!";
                        return result;
                    }
                }

                if (!RegexCheck.IsNUM_CustomRange(model.IsPermanentScore.ToString(), 0, 1))
                {
                    paramVerify = false;
                    result.code = ((int)ResultCodeEnum.失败).ToString();
                    result.msg = "是否永久积分参数不合法!";
                    return result;
                }
                else
                {
                    //如果积分类型为增加时则判断此字段
                    if (model.TradeType == 0)
                    {
                        if (model.IsPermanentScore == 0 && !RegexCheck.IsDateTime(model.ExpirationTime.ToString()))
                        {
                            paramVerify = false;
                            result.code = ((int)ResultCodeEnum.失败).ToString();
                            result.msg = "非永久积分必须传入到期时间!";
                            return result;
                        }
                    }
                }
                #endregion

                //参数校验通过后开始执行存储过程
                if (paramVerify)
                {
                    //步骤3.执行存储过程,积分兑换操作
                    SqlParameter[] parameters = new SqlParameter[9];
                    parameters[0] = new SqlParameter("@UserId", token.UserId);
                    parameters[1] = new SqlParameter("@TradeScore", model.TradeScore);
                    parameters[2] = new SqlParameter("@TradeType", model.TradeType);
                    parameters[3] = new SqlParameter("@TradeTitle", model.TradeTitle);
                    parameters[4] = new SqlParameter("@TradeDescription", model.@TradeDescription);
                    parameters[5] = new SqlParameter("@SourceSystemCode", model.SourceSystemCode);
                    parameters[6] = new SqlParameter("@IsPermanentScore", model.IsPermanentScore);
                    parameters[7] = new SqlParameter("@ExpirationTime", model.ExpirationTime);
                    parameters[8] = new SqlParameter("@ScoreActionId", model.ScoreActionId);

                    DataSet ds = SqlHelper.ExecuteDataSet(CommandType.StoredProcedure, "Proc_ScoreTrade", parameters);

                    if (ds.Tables[0].Rows[0][0].ToString() == "OK")
                    {
                        result.code = ((int)ResultCodeEnum.成功).ToString();
                        result.msg = "操作成功";
                    }
                    else
                    {
                        result.code = ((int)ResultCodeEnum.失败).ToString();
                        result.msg = "操作失败,稍后再试";
                    }
                }
            }
            catch (Exception ex)
            {
                result.code = ((int)ResultCodeEnum.异常).ToString();
                result.msg = "操作失败,程序异常";
                LogMsgPrint.Append("\r\n时间:" + DateTime.Now);
                LogMsgPrint.Append("\r\n错误原因:" + ex.Message);
                LogMsgPrint.Append(result.msg);
                log.Error(LogMsgPrint.ToString());
            }

            LogMsgPrint.Append(result.msg);
            log.Info(LogMsgPrint.ToString());
            return result;
        }
        #endregion
}

6.3 接参模型

public  class ScoreTrade_Model
    {
        /// <summary>
        /// 交易积分
        /// </summary>
        public int TradeScore { get; set; }

        /// <summary>
        /// 交易类型 0=增加积分,1=扣减积分
        /// </summary>
        public int TradeType { get; set; }
        /// <summary>
        /// 交易标题限50字
        /// </summary>
        public string TradeTitle { get; set; }
        /// <summary>
        /// 交易描述限100字
        /// </summary>
        public string TradeDescription { get; set; }

        /// <summary>
        /// 积分来源系统代码
        /// </summary>
        public int SourceSystemCode { get; set; }

        /// <summary>
        /// 是否永久积分 0=非永久,1=永久积分
        /// </summary>
        public int IsPermanentScore { get; set; }

        /// <summary>
        /// 积分到期时间(可为空),无到期时间则为永久积分
        /// </summary>
        public  DateTime? ExpirationTime { get; set; }

        /// <summary>
        /// 交易时间
        /// </summary>
        public DateTime TradeTime { get; set; }

        /// <summary>
        /// 积分规则ID ;(默认值:88888是系统增加的积分,未通过积分规则)该字段对应QX_Member_ScoreSetting表
        /// </summary>
        public int ScoreActionId { get; set; } = 88888;

    }

6.4 存储过程

USE [yanshi_db]
GO
/****** Object:  StoredProcedure [dbo].[Proc_ScoreTrade]    Script Date: 2022/3/2 9:37:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		SJP
-- Create date: 2021-5-27
-- update:2022-2-17 CP
-- Description:积分交易操作(积分增加、扣减)
-- =============================================
ALTER PROCEDURE [dbo].[Proc_ScoreTrade]
	@UserId int,
	@ScoreActionId int,
	@TradeScore int,
	@TradeType int,
	@TradeTitle nvarchar(50),
	@TradeDescription nvarchar(100)=null,
	@SourceSystemCode int,
	@IsPermanentScore int,
	@ExpirationTime datetime=null
AS
BEGIN
set xact_abort on
begin transaction

declare @BeforeScore int,@AfterScore int


select  @BeforeScore=convert(int,Score)  from QX_Member where UserId=@UserId

--如果交易类型为扣减,则计算扣减后积分余额
 if(@TradeType=1)
 begin
 set @AfterScore=@BeforeScore-@TradeScore
 end

--如果交易类型为增加,则计算增加后积分余额
  if(@TradeType=0)
 begin
 set @AfterScore=@BeforeScore+@TradeScore
 end

 --top1 先插入积分交易记录

   INSERT INTO [dbo].[QX_Score_TradeDetails]
           ([UserId]
           ,[BeforeScore]
           ,[AfterScore]
           ,[TradeScore]
           ,[TradeType]
           ,[TradeTime]
           ,[TradeTitle]
           ,[TradeDescription]
           ,[SourceSystemCode]
           ,[IsPermanentScore]
           ,[ExpirationTime]
		   ,[ScoreActionId])
     VALUES
           (@UserId
           ,@BeforeScore
           ,@AfterScore
           ,@TradeScore
           ,@TradeType
           ,getdate()
           ,@TradeTitle
           ,@TradeDescription
           ,@SourceSystemCode
           ,@IsPermanentScore
           ,@ExpirationTime
		   ,@ScoreActionId)

  --top2修改用户账户积分余额
   update user_table set Score=@AfterScore where UserId=@UserId;


	if( @@error=0)
		begin
			commit transaction;
			select 'OK' as result
		end
		else
		begin 
			select 'Error' as result
			rollback transaction;		
			return;
		end

END

七、重点说明

7.1.积分规则缓存

积分规则在“增加”、“修改”、“删除”时一定要清空缓存

7.2.签到记录添加

签到记录添加时,应先获取用户上次签到的的信息,拿当前时间和上次签到时间进行运算;

代码如下

 #region 添加
        /// <summary>
        /// 添加  返回-1:用户ID是0无效
        /// </summary> 
        /// <returns></returns>
        public static int Add(QX_SignInLogModel model)
        {
            int result = 0;
            using (var conn = SqlHelper.SqlConnection())
            {
                try
                {
                    using (SqlTransaction trans = conn.BeginTransaction())
                    {
                        try
                        {
                            if (model.UserId > 0)
                            {
                                //1.上次签到
                                string selectSql = $@"select top(1) * from QX_SignInLog where UserId={model.UserId} order by QX_SignInLogID desc";
                                QX_SignInLogModel signInLog = conn.Query<QX_SignInLogModel>(selectSql, model, trans).SingleOrDefault();

                                //2.赋值
                                model.CreateTime = DateTime.Now;

                                if (signInLog != null)
                                {
                                    model.DiscrepancyDay = DateTime.Now.Date.Subtract(signInLog.SignInTime.Date).Days;
                                }    

                                //3.记录签到
                                StringBuilder sql = new StringBuilder();
                                sql.Append(@"insert into QX_SignInLog(UserId, DiscrepancyDay, IsReplenish, SignInTime, CreateTime) 
                                        values(@UserId, @DiscrepancyDay, @IsReplenish, @SignInTime, @CreateTime)");
                                result = conn.Execute(sql.ToString(), model, trans);

                                //提交事务(持久化数据)
                                trans.Commit();
                            }
                            else
                            {
                                result= - 1; //意思是用户ID是0;无效
                            }
                        }
                        catch (Exception e)
                        {
                            //事务回滚
                            trans.Rollback();
                            log.Error(e.LogErrorTxt());
                        }
                        
                    }
                }
                catch (Exception e)
                {
                    log.Error(e.LogErrorTxt()); 
                }
            }

            return result;
        }
        #endregion

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是一个基于SpringBoot的签到连续签到业务逻辑接口的实现。 首先,我们定义一个签到记录的实体类,包含用户ID、签到日期和是否连续签到等属性: ```java @Entity @Table(name = "sign_record") public class SignRecord { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private Integer userId; private LocalDate date; private boolean isContinued; // 省略getter和setter } ``` 接下来,我们定义一个签到服务的接口,包含签到和获取签到记录等方法: ```java public interface SignService { /** * 签到 * @param userId 用户ID * @return 签到记录 */ SignRecord signIn(Integer userId); /** * 获取用户签到记录 * @param userId 用户ID * @return 签到记录列表 */ List<SignRecord> getSignRecords(Integer userId); } ``` 然后,我们实现这个接口: ```java @Service public class SignServiceImpl implements SignService { @Autowired private SignRecordRepository signRecordRepository; @Override public SignRecord signIn(Integer userId) { LocalDate today = LocalDate.now(); Optional<SignRecord> lastRecordOptional = signRecordRepository.findTopByUserIdOrderByDateDesc(userId); if (lastRecordOptional.isPresent()) { SignRecord lastRecord = lastRecordOptional.get(); if (lastRecord.getDate().equals(today)) { // 已经签到过了 return lastRecord; } else if (lastRecord.getDate().plusDays(1).equals(today)) { // 连续签到 lastRecord.setContinued(true); } else { // 非连续签到 lastRecord.setContinued(false); } lastRecord.setDate(today); signRecordRepository.save(lastRecord); return lastRecord; } else { // 第一次签到 SignRecord record = new SignRecord(); record.setUserId(userId); record.setDate(today); record.setContinued(false); signRecordRepository.save(record); return record; } } @Override public List<SignRecord> getSignRecords(Integer userId) { return signRecordRepository.findByUserIdOrderByDateDesc(userId); } } ``` 在签到接口中,我们首先获取用户最近一次的签到记录,如果今天已经签到了,则直接返回该记录;如果今天是连续签到,则更新记录的连续签到标记并保存;否则,更新记录为非连续签到并保存。如果没有找到用户的签到记录,说明这是用户的第一次签到,则新建一条签到记录并保存。 最后,我们还需要定义一个签到记录的仓库接口: ```java public interface SignRecordRepository extends JpaRepository<SignRecord, Integer> { Optional<SignRecord> findTopByUserIdOrderByDateDesc(Integer userId); List<SignRecord> findByUserIdOrderByDateDesc(Integer userId); } ``` 这个仓库接口继承了Spring Data JPA的`JpaRepository`,并定义了两个查询方法,分别用于查找用户最近一次的签到记录和用户所有的签到记录。 以上就是一个简单的签到连续签到业务逻辑接口的实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙-极纪元JJY.Cheng

客官,1分钱也是爱,给个赏钱吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值