Browse Source

服务工单需求

Shan9312 2 months ago
parent
commit
8c24b3df08
46 changed files with 3186 additions and 111 deletions
  1. 6 0
      app.json
  2. 1 1
      app.wxss
  3. BIN
      images/workbench/fuwudan.jpeg
  4. BIN
      images/workbench/fuwudan.png
  5. 1 1
      miniprogram_npm/lin-ui/behaviors/rules.js
  6. 0 0
      miniprogram_npm/lin-ui/button/index.wxss
  7. 1 1
      miniprogram_npm/lin-ui/checkbox-group/index.wxml
  8. 2 3
      miniprogram_npm/lin-ui/checkbox/index.wxml
  9. 3 3
      miniprogram_npm/lin-ui/form-item/index.wxml
  10. 1 6
      miniprogram_npm/lin-ui/form-item/index.wxss
  11. 19 1
      miniprogram_npm/lin-ui/image-clipper/index.wxml
  12. 1 1
      miniprogram_npm/lin-ui/input/index.wxml
  13. 1 3
      miniprogram_npm/lin-ui/input/index.wxss
  14. 1 0
      miniprogram_npm/lin-ui/price/index.js
  15. 1 0
      miniprogram_npm/lin-ui/price/index.json
  16. 6 0
      miniprogram_npm/lin-ui/price/index.wxml
  17. 1 0
      miniprogram_npm/lin-ui/price/index.wxss
  18. 1 1
      miniprogram_npm/lin-ui/radio-group/index.wxml
  19. 1 3
      miniprogram_npm/lin-ui/search-bar/index.wxss
  20. 1 10
      miniprogram_npm/lin-ui/textarea/index.wxss
  21. 1 1
      package-lock.json
  22. 5 4
      pages/login/login.js
  23. 436 0
      pages/workbench/acceptFill/acceptFill.js
  24. 3 0
      pages/workbench/acceptFill/acceptFill.json
  25. 151 0
      pages/workbench/acceptFill/acceptFill.wxml
  26. 225 0
      pages/workbench/acceptFill/acceptFill.wxss
  27. 302 0
      pages/workbench/dailyFill/dailyFill.js
  28. 6 0
      pages/workbench/dailyFill/dailyFill.json
  29. 105 0
      pages/workbench/dailyFill/dailyFill.wxml
  30. 157 0
      pages/workbench/dailyFill/dailyFill.wxss
  31. 221 0
      pages/workbench/historyFill/historyFill.js
  32. 6 0
      pages/workbench/historyFill/historyFill.json
  33. 112 0
      pages/workbench/historyFill/historyFill.wxml
  34. 124 0
      pages/workbench/historyFill/historyFill.wxss
  35. 67 0
      pages/workbench/serviceOrderDetail/serviceOrderDetail.js
  36. 6 0
      pages/workbench/serviceOrderDetail/serviceOrderDetail.json
  37. 121 0
      pages/workbench/serviceOrderDetail/serviceOrderDetail.wxml
  38. 114 0
      pages/workbench/serviceOrderDetail/serviceOrderDetail.wxss
  39. 407 0
      pages/workbench/serviceTicket/serviceTicket.js
  40. 9 0
      pages/workbench/serviceTicket/serviceTicket.json
  41. 181 0
      pages/workbench/serviceTicket/serviceTicket.wxml
  42. 269 0
      pages/workbench/serviceTicket/serviceTicket.wxss
  43. 0 2
      pages/workbench/siteService/siteService.js
  44. 5 1
      pages/workbench/workbench.js
  45. 2 1
      project.private.config.json
  46. 103 68
      utils/util.js

+ 6 - 0
app.json

@@ -10,6 +10,12 @@
     "pages/workbench/workbench",
     "pages/workbench/visitRecord/visitRecord",
 
+    "pages/workbench/serviceTicket/serviceTicket",
+    "pages/workbench/dailyFill/dailyFill",
+    "pages/workbench/acceptFill/acceptFill",
+    "pages/workbench/historyFill/historyFill",
+    "pages/workbench/serviceOrderDetail/serviceOrderDetail",
+    
     "pages/workbench/siteService/siteService",
     "pages/workbench/siteServiceAdd/siteServiceAdd",
     "pages/workbench/siteServiceEdit/siteServiceEdit",

+ 1 - 1
app.wxss

@@ -1,5 +1,5 @@
 page{
-  background-color:#f5f5f5;
+  background-color:#f2f2f2;
   height:100%;
 }
 .customer_bx{background:#fff;width:480rpx;height:980rpx;position:absolute;top:90rpx;z-index:99999; margin-left:230rpx;border:1px solid #eee; } 

BIN
images/workbench/fuwudan.jpeg


BIN
images/workbench/fuwudan.png


+ 1 - 1
miniprogram_npm/lin-ui/behaviors/rules.js

@@ -1 +1 @@
-import Schema from"../common/async-validator/index";import validator from"../behaviors/validator";export default Behavior({behaviors:[validator],properties:{rules:{type:[Object,Array],value:[]},tipType:{type:String,value:"toast",options:["toast","message","text"]}},data:{schema:"",tipFun:{message:"showMessage",toast:"showToast"},tipContent:{message:"content",toast:"title"},errorText:"",errors:[]},methods:{initRules(){const{rules:t}=this.data;t&&("[object Object]"===Object.prototype.toString.call(t)&&(this.data.rules=[t]),this.data.rules.forEach(t=>{t.trigger?"string"!=typeof t.trigger||(t.trigger=[t.trigger]):t.trigger=[]}))},getNeedValidateRule(t){const e=this.data.name,{rules:a}=this.data;if(!a)return;const r=t?a.filter(e=>e.trigger.indexOf(t)>-1):a,s=new Schema({[e]:r});return this.setData({schema:s}),r},validatorData(t,e){const{tipType:a,tipFun:r,tipContent:s}=this.data;this.getNeedValidateRule(e)&&(Object.getOwnPropertyNames(t).forEach(e=>{""===t[e]&&(t[e]=void 0)}),this.data.schema.validate(t,t=>{if(this.setData({errors:t||[]}),this.triggerEvent("linvalidate",{errors:t,isError:!!t}),t&&a){const e=r[a],i=s[a];return"text"===a?(this.setData({errorText:t[0].message}),t):wx.lin&&wx.lin[e]?(wx.lin[e]&&wx.lin[e]({[i]:t[0].message,duration:1500,mask:!1}),t):(t)}!t&&a&&this.setData({errorText:""})}))}}});
+import Schema from"../common/async-validator/index";import validator from"../behaviors/validator";export default Behavior({behaviors:[validator],properties:{rules:{type:[Object,Array],value:[]},tipType:{type:String,value:"toast",options:["toast","message","text"]}},data:{schema:"",tipFun:{message:"showMessage",toast:"showToast"},tipContent:{message:"content",toast:"title"},errorText:"",errors:[]},methods:{initRules(){const{rules:t}=this.data;t&&("[object Object]"===Object.prototype.toString.call(t)&&(this.data.rules=[t]),this.data.rules.forEach(t=>{t.trigger?"string"!=typeof t.trigger||(t.trigger=[t.trigger]):t.trigger=[]}))},getNeedValidateRule(t){const e=this.data.name,{rules:a}=this.data;if(!a)return;const r=t?a.filter(e=>e.trigger.indexOf(t)>-1):a,s=new Schema({[e]:r});return this.setData({schema:s}),r},validatorData(t,e){const{tipType:a,tipFun:r,tipContent:s}=this.data;this.getNeedValidateRule(e)&&(Object.getOwnPropertyNames(t).forEach(e=>{""===t[e]&&(t[e]=void 0)}),this.data.schema.validate(t,t=>{if(this.setData({errors:t||[]}),this.triggerEvent("linvalidate",{errors:t,isError:!!t}),t&&a){const e=r[a],i=s[a];return"text"===a?(this.setData({errorText:t[0].message}),t):wx.lin&&wx.lin[e]?(wx.lin[e]&&wx.lin[e]({[i]:t[0].message,duration:1500,mask:!1}),t):(wx.showToast({icon:"none",title:`请在页面内引入${a}组件`}),t)}!t&&a&&this.setData({errorText:""})}))}}});

File diff suppressed because it is too large
+ 0 - 0
miniprogram_npm/lin-ui/button/index.wxss


+ 1 - 1
miniprogram_npm/lin-ui/checkbox-group/index.wxml

@@ -1,4 +1,4 @@
-<view class="l-class checkbox-group checkbox-group-{{placement}}" >
+<view class="l-class checkbox-group checkbox-group-{{placement}}">
   <slot></slot> 
 </view>
   <l-error-tip l-error-text-class="l-error-text l-error-text-class" errorText="{{errorText}}" wx:if="{{errorText}}"/>

+ 2 - 3
miniprogram_npm/lin-ui/checkbox/index.wxml

@@ -1,8 +1,7 @@
-<view mut-bind:lintap="onCheckboxChangeTap" mut-bind:tap="onCheckboxChangeTap" class="label label-{{placement}} label-placement-{{parentPlacement}} {{disabled ? 'label-disabled l-disabled-class' : 'l-class'}}" style="justify-content:flex-end">
-        <view class="checkbox-{{placement}} l-icon-class" style="color:{{checked ? selectColor : (disabled ? disabledColor : color)}};font-size: {{size}};">
+<view mut-bind:lintap="onCheckboxChangeTap" mut-bind:tap="onCheckboxChangeTap" class="label label-{{placement}} label-placement-{{parentPlacement}} {{disabled ? 'label-disabled l-disabled-class' : 'l-class'}}">
+        <view class="checkbox-{{placement}} l-icon-class" style="color:{{checked ? selectColor : (disabled ? disabledColor : color)}};font-size: {{size}}">
             <slot wx:if="{{custom}}" name="icon"/>
             <view wx:else class="iconfont {{checked? 'icon-select': 'icon-unselect'}}"></view>
         </view>
         <slot/>
 </view>
- 

+ 3 - 3
miniprogram_npm/lin-ui/form-item/index.wxml

@@ -1,5 +1,5 @@
-<view class="cyj-form-bx l-form-item-class form-item-container {{'label-' + labelPlacement}} {{tipType === 'text' ? 'textHeight': ''}}">
-    <view class="cyj-form-item1 l-form-label-class label-text {{isRequired ? 'label-text-required': ''}} {{'label-text-' + labelPlacement+ '-' + alignItems}}" style="min-width: {{labelPlacement==='row' ? labelWidth : '100%'}};max-width: {{labelPlacement==='row' ? labelWidth : '100%'}}">
+<view class="l-form-item-class form-item-container {{'label-' + labelPlacement}} {{tipType === 'text' ? 'textHeight': ''}}">
+    <view class="l-form-label-class label-text {{isRequired ? 'label-text-required': ''}} {{'label-text-' + labelPlacement+ '-' + alignItems}}" style="min-width: {{labelPlacement==='row' ? labelWidth : '100%'}};max-width: {{labelPlacement==='row' ? labelWidth : '100%'}}">
         <view wx:if="{{labelSlot}}">
             <slot name="label"/>
         </view>
@@ -7,7 +7,7 @@
             {{label}}
         </view>
     </view>
-    <view class="label-content l-form-content-class cyj-form-item2" >
+    <view class="label-content l-form-content-class">
         <slot/>
     </view>
     <l-error-tip class="error-text" l-error-text-class="l-error-text-class" errorText="{{errorText}}" wx:if="{{errorText}}"/>

+ 1 - 6
miniprogram_npm/lin-ui/form-item/index.wxss

@@ -1,6 +1 @@
-.form-item-container{display:flex;border-bottom:1px solid #eee;color:#777;padding:0 20rpx;position:relative}.form-item-container.textHeight{margin-bottom:44rpx}.form-item-container.label-column{align-items:left;flex-direction:column}.form-item-container.label-column .label-text{line-height:44rpx}.form-item-container.label-row{align-items:center;flex-direction:row}.form-item-container.label-row .label-text{line-height:88rpx}.form-item-container .label-text{display:flex;line-height:88rpx}.form-item-container .label-text-column-start{justify-content:flex-start}.form-item-container .label-text-column-end{justify-content:flex-end}.form-item-container .label-text-column-center{justify-content:center}.form-item-container .label-text-row-start{justify-content:flex-start}.form-item-container .label-text-row-end{justify-content:flex-end}.form-item-container .label-text-row-center{justify-content:center}.form-item-container .label-content{flex:1}.form-item-container .label-text-required::before{display:inline-block;margin-right:4px;color:#f5222d;font-family:SimSun,sans-serif;content:'*'}.error-text{text-align:right;line-height:44rpx;color:#f56c6c;font-size:12px;position:absolute;top:100%;left:0;padding-left:24rpx}.row{display:none!important}
-
-
-/* 自定义的样式。为了表单左右分布 */
-.cyj-form-bx{display: flex; flex-flow:  row nowrap;justify-content: space-between;}
-.cyj-form-item2{text-align:right;}
+.form-item-container{display:flex;border-bottom:1px solid #eee;color:#777;padding:0 20rpx;position:relative}.form-item-container.textHeight{margin-bottom:44rpx}.form-item-container.label-column{align-items:left;flex-direction:column}.form-item-container.label-column .label-text{line-height:44rpx}.form-item-container.label-row{align-items:center;flex-direction:row}.form-item-container.label-row .label-text{line-height:88rpx}.form-item-container .label-text{display:flex;line-height:88rpx}.form-item-container .label-text-column-start{justify-content:flex-start}.form-item-container .label-text-column-end{justify-content:flex-end}.form-item-container .label-text-column-center{justify-content:center}.form-item-container .label-text-row-start{justify-content:flex-start}.form-item-container .label-text-row-end{justify-content:flex-end}.form-item-container .label-text-row-center{justify-content:center}.form-item-container .label-content{flex:1}.form-item-container .label-text-required::before{display:inline-block;margin-right:4px;color:#f5222d;font-family:SimSun,sans-serif;content:'*'}.error-text{text-align:right;line-height:44rpx;color:#f56c6c;font-size:12px;position:absolute;top:100%;left:0;padding-left:24rpx}.row{display:none!important}

+ 19 - 1
miniprogram_npm/lin-ui/image-clipper/index.wxml

@@ -6,7 +6,25 @@
             
             
             
-           
+            
+            
+            <view class="clip-content">
+                <view class="clip-content-top bg-transparent" style="height: {{cutY}}px;transition-property: {{cutAnimation ? '' : 'background'}}"></view>
+                <view class="clip-content-middle" style="height: {{clipHeight}}px;">
+                    
+                    
+                    
+                    
+                    
+                    
+                    <view class="clip-content-middle-left bg-transparent" style="width: {{cutX}}px;transition-property: {{cutAnimation ? '' : 'background'}}"></view>
+                    <view class="clip-content-middle-center" style="width: {{clipWidth}}px;height: {{clipHeight}}px;transition-property: {{cutAnimation ? '' : 'background'}}">
+                        <view class="clip-edge clip-edge-{{index < 2 ? 'top' : 'bottom'}}-{{index === 0 || index === 2 ? 'left' : 'right'}}" wx:for="{{4}}" wx:for-index="index" wx:key="index" style="left: {{index === 0 || index === 2 ? 0 : 'auto'}};right: {{index === 1 || index === 3 ? 0 : 'auto'}};top: {{index < 2 ? 0 : 'auto'}};bottom: {{index > 1 ? 0 : 'auto'}}"></view>
+                    </view>
+                    <view class="clip-content-middle-right flex-auto bg-transparent" style="transition-property: {{cutAnimation ? '' : 'background'}}"></view>
+                </view>
+                <view class="clip-content-footer flex-auto bg-transparent" style="transition-property: {{cutAnimation ? '' : 'background'}}"></view>
+            </view>
         </view>
         
         <image class="cropper-image" binderror="imageLoad" bindload="imageLoad" bind:touchstart="imageTouchStart" bind:touchmove="imageTouchMove" bind:touchend="imageTouchEnd" src="{{imageUrl}}" mode="widthFix" wx:if="{{imageUrl}}" style="width: {{imageWidth ? imageWidth + 'px' : 'auto'}};height: {{imageHeight ? imageHeight + 'px' : 'auto'}};transform: translate3d({{imageLeft - imageWidth / 2}}px, {{imageTop - imageHeight / 2}}px,0) scale({{scale}}) rotate({{angle}}deg); transition-duration: {{cutAnimation ? 0.35 : 0}}s;"/>

+ 1 - 1
miniprogram_npm/lin-ui/input/index.wxml

@@ -6,7 +6,7 @@
     <text><text class="text-require" wx:if="{{required}}">* </text>{{label}}<text wx:if="{{colon}}">:</text>
     </text>
   </view>
-  <view wx:else hidden="{{hideLabel}}" class="form-label l-label-class form-label-{{labelLayout}}" style='{{labelLayout !== "top" ? "width:"+ labelWidth+ "rpx;" : "" }} height:{{labelLayout=== "top" ? labelWidth + "rpx" : ""  }}'>
+  <view wx:else hidden="{{hideLabel}}" class="form-label l-label-class form-label-{{labelLayout}}" style='{{labelLayout !== "top" ? "width:"+ labelWidth+ "rpx;" : "" }} height:{{labelLayout=== "top" ? labelWidth + "rpx" : "" }}'>
     <slot name="left"/>
   </view>
   

+ 1 - 3
miniprogram_npm/lin-ui/input/index.wxss

@@ -1,3 +1 @@
-.form-item{position:relative;font-size:28rpx;color:#333;height:88rpx;display:flex;flex-direction:row;align-items:center;padding-right:25rpx;box-sizing:border-box}.row{position:absolute;bottom:0;right:0;height:2rpx;width:730rpx;background:#f3f3f3}.text-require{color:#e23;vertical-align:middle}.form-label{display:flex;flex-direction:row;align-items:center;height:88rpx;padding-left:25rpx;padding-right:15rpx;box-sizing:border-box}.disabled{color:#9a9a9a!important}.mask{position:absolute;z-index:999;height:100%;width:100%}.form-label-right{justify-content:flex-end}.form-label-left{justify-content:flex-start}.input{height:100%;line-height:100%;flex:1}.close{height:36rpx;width:36rpx;background:#ddd;display:flex;flex-direction:row;align-items:center;justify-content:center;border-radius:50%;margin-right:20rpx}
-.pls-class{color:#333}
-.hideLabel{padding-left:25rpx}.l-eye{padding:10rpx}.l-eye-text{color:#3963bc!important}.l-eye-password{color:rgba(57,99,188,.6)!important}
+.form-item{position:relative;font-size:28rpx;color:#333;height:88rpx;display:flex;flex-direction:row;align-items:center;padding-right:25rpx;box-sizing:border-box}.row{position:absolute;bottom:0;right:0;height:2rpx;width:730rpx;background:#f3f3f3}.text-require{color:#e23;vertical-align:middle}.form-label{display:flex;flex-direction:row;align-items:center;height:88rpx;padding-left:25rpx;padding-right:15rpx;box-sizing:border-box}.disabled{color:#9a9a9a!important}.mask{position:absolute;z-index:999;height:100%;width:100%}.form-label-right{justify-content:flex-end}.form-label-left{justify-content:flex-start}.input{height:100%;line-height:100%;flex:1}.close{height:36rpx;width:36rpx;background:#ddd;display:flex;flex-direction:row;align-items:center;justify-content:center;border-radius:50%;margin-right:20rpx}.pls-class{color:#9a9a9a}.hideLabel{padding-left:25rpx}.l-eye{padding:10rpx}.l-eye-text{color:#3963bc!important}.l-eye-password{color:rgba(57,99,188,.6)!important}

+ 1 - 0
miniprogram_npm/lin-ui/price/index.js

@@ -0,0 +1 @@
+import validator from"../behaviors/validator";Component({externalClasses:["l-deleted-class","l-unit-class","l-value-class","l-class","l-decimal-class","l-dot-class"],behaviors:[validator],properties:{unit:{type:String,value:"¥"},size:{type:String,value:"28"},color:{type:String,value:"#3963BC"},bold:{type:String,value:"500"},unitColor:String,unitSize:String,unitBold:String,value:{type:String,value:"0.00"},mode:{type:String,value:"number",options:["number","text"]},valueColor:String,valueSize:String,valueBold:String,deleted:Boolean,delColor:String,reserveDigit:{type:Number,value:2},autofix:Boolean},data:{priceInteger:{type:String,value:"0"},priceDecimal:{type:String,value:"00"}},observers:{value:function(){this.reserveNumber()}},methods:{reserveNumber(){this.setData({priceInteger:null,priceDecimal:null});const e=Number(this.data.value);if(!(isNaN(Number(e))||"text"===this.data.mode)&&this.data.autofix){const t=e.toFixed(this.data.reserveDigit).toString().split(".");this._setPrice(t)}else{const e=this.data.value.split(".");this._setPrice(e)}},_setPrice(e){if(1===e.length)this.setData({priceInteger:e[0]});else{if(2!==e.length)throw"price 格式有误,请仔细检查!";this.setData({priceInteger:e[0],priceDecimal:e[1]})}}}});

+ 1 - 0
miniprogram_npm/lin-ui/price/index.json

@@ -0,0 +1 @@
+{"component":true,"usingComponents":{}}

+ 6 - 0
miniprogram_npm/lin-ui/price/index.wxml

@@ -0,0 +1,6 @@
+<view class='price-container l-class {{deleted ? "price-del l-deleted-class" : ""}}' style="color: {{delColor?delColor:color}}">
+  
+  <text class="l-unit-class" style="color: {{unitColor?unitColor:color}}; font-size: {{unitSize?unitSize:size}}rpx; font-weight: {{unitBold?unitBold:bold}}">{{unit}}</text>
+  
+  <text class="l-value-class" style="color: {{valueColor?valueColor:color}}; font-size: {{valueSize?valueSize:size}}rpx; font-weight: {{valueBold?valueBold:bold}}">{{priceInteger}}<text class="l-dot-class">{{priceDecimal?'.':''}}</text><text class="l-decimal-class">{{priceDecimal?priceDecimal:''}}</text></text>
+</view>

+ 1 - 0
miniprogram_npm/lin-ui/price/index.wxss

@@ -0,0 +1 @@
+.price-del{text-decoration:line-through!important}.price-container{display:inline-block;text-align:center;color:#3963bc;font-size:28rpx}

+ 1 - 1
miniprogram_npm/lin-ui/radio-group/index.wxml

@@ -1,4 +1,4 @@
-<view class="l-class radio-group radio-group-{{placement}}" style="justify-content:flex-end">
+<view class="l-class radio-group radio-group-{{placement}}">
     <slot></slot>
 </view>
 <l-error-tip l-error-text-class="l-error-text l-error-text-class" errorText="{{errorText}}" wx:if="{{errorText}}"/>

+ 1 - 3
miniprogram_npm/lin-ui/search-bar/index.wxss

@@ -1,3 +1 @@
-.search-bar{display:flex;flex-direction:row;align-items:center;padding:0 20rpx;box-sizing:border-box;width:100%}.search-input{height:60rpx;background-color:#f3f3f3;display:flex;flex-direction:row;flex:1;align-items:center;padding-left:30rpx;box-sizing:border-box}.search-input-primary{border-radius:8rpx}.search-input-circle{border-radius:30rpx}.cancel{font-size:28rpx;color:#666;display:flex;align-items:center;width:60rpx;justify-content:center;height:60rpx;margin-left:15rpx}.input{height:40rpx;line-height:40rpx;flex:1;margin-left:15rpx;font-size:28rpx;color:#666}.input-center{text-align:center}.input-left{text-align:left}.close-wrap{padding:10rpx}.close{height:30rpx;width:30rpx;background:#ddd;display:flex;align-items:center;justify-content:center;border-radius:50%;padding-top:3rpx;box-sizing:border-box;margin-right:15rpx}
-.pls-class{color:#bdbdbd;font-size:28rpx}
-.icon-container{display:flex;flex-direction:row;align-items:center;margin-right:15rpx}.city{font-size:28rpx;color:#333;margin-right:10rpx}
+.search-bar{display:flex;flex-direction:row;align-items:center;padding:0 20rpx;box-sizing:border-box;width:100%}.search-input{height:60rpx;background-color:#f3f3f3;display:flex;flex-direction:row;flex:1;align-items:center;padding-left:30rpx;box-sizing:border-box}.search-input-primary{border-radius:8rpx}.search-input-circle{border-radius:30rpx}.cancel{font-size:28rpx;color:#666;display:flex;align-items:center;width:60rpx;justify-content:center;height:60rpx;margin-left:15rpx}.input{height:40rpx;line-height:40rpx;flex:1;margin-left:15rpx;font-size:28rpx;color:#666}.input-center{text-align:center}.input-left{text-align:left}.close-wrap{padding:10rpx}.close{height:30rpx;width:30rpx;background:#ddd;display:flex;align-items:center;justify-content:center;border-radius:50%;padding-top:3rpx;box-sizing:border-box;margin-right:15rpx}.pls-class{color:#bdbdbd;font-size:28rpx}.icon-container{display:flex;flex-direction:row;align-items:center;margin-right:15rpx}.city{font-size:28rpx;color:#333;margin-right:10rpx}

+ 1 - 10
miniprogram_npm/lin-ui/textarea/index.wxss

@@ -1,10 +1 @@
-.form-item{position:relative;font-size:28rpx;color:#333;width:100%;display:flex;flex-direction:column;align-items:center;box-sizing:border-box}.disabled{color:#9a9a9a!important}.mask{position:absolute;z-index:999;height:100%;width:100%}.textarea{width:100%;box-sizing:border-box;font-size:28rpx;color:#333;height:200rpx;line-height:40rpx;flex:1;min-height:88rpx}.textarea-auto-height{width:100%;box-sizing:border-box;font-size:28rpx;color:#333}.default-border{position:relative;font-size:28rpx;color:#333;width:100%;display:flex;flex-direction:column;align-items:center;box-sizing:border-box;padding:25rpx}
-
-
-
-/* .border{border-radius:4rpx;border:1rpx solid #d8dee5} */
-/* 产品要求的去掉框线颜色-cyj自定义 */
-.border{border-radius:4rpx; }
-
-.pls-class{color:#333}
-.indicator{width:95%;text-align:right;margin-bottom:15rpx;color:#9a9a9a;font-size:28rpx}
+.form-item{position:relative;font-size:28rpx;color:#333;width:100%;display:flex;flex-direction:column;align-items:center;box-sizing:border-box}.disabled{color:#9a9a9a!important}.mask{position:absolute;z-index:999;height:100%;width:100%}.textarea{width:100%;box-sizing:border-box;font-size:28rpx;color:#333;height:200rpx;line-height:40rpx;flex:1;min-height:88rpx}.textarea-auto-height{width:100%;box-sizing:border-box;font-size:28rpx;color:#333}.default-border{position:relative;font-size:28rpx;color:#333;width:100%;display:flex;flex-direction:column;align-items:center;box-sizing:border-box;padding:25rpx}.border{border-radius:4rpx;border:1rpx solid #d8dee5}.pls-class{color:#9a9a9a}.indicator{width:95%;text-align:right;margin-bottom:15rpx;color:#9a9a9a}

+ 1 - 1
package-lock.json

@@ -6,7 +6,7 @@
   "dependencies": {
     "lin-ui": {
       "version": "0.9.4",
-      "resolved": "https://registry.npm.taobao.org/lin-ui/download/lin-ui-0.9.4.tgz",
+      "resolved": "s://registry.npm.taobao.org/lin-ui/download/lin-ui-0.9.4.tgz",
       "integrity": "sha1-PzSWGAmqF11Jwy5CRPt9saRkGcw="
     }
   }

+ 5 - 4
pages/login/login.js

@@ -5,8 +5,9 @@ Page({
 
   data: {
     isHiden: true,
- 
-   userurl: 'https://kptyun.cn/',//正式地址
+//  http://210.16.189.72:8099/authdata/GetDataByNames
+    userurl:'http://210.16.189.72:8099/' ,
+      // 'https://kptyun.cn/',//正式地址
    // userurl: 'http://192.168.1.57:8084/',//刘欢地址
    // userurl: 'http://210.16.189.72:8099/',//测试地址
     username: '',
@@ -164,7 +165,7 @@ Page({
      }
 
       
-
+     
       wx.setStorageSync('g_url', g_url)
       wx.setStorageSync('g_token', g_token)
       
@@ -172,7 +173,7 @@ Page({
 
       util.getDataByName({ 'name': 'findByUserPastureName', 'parammaps': { 'jwt_username': username } }, function(e){
          console.log(e)
-   
+         wx.setStorageSync('g_userId',  e.data.list[0].employeId)
 
          var g_lgName = e.data.list[0].employeName
          var g_countName = e.data.list[0].username

+ 436 - 0
pages/workbench/acceptFill/acceptFill.js

@@ -0,0 +1,436 @@
+var util = require('../../../utils/util.js')
+const app = getApp()
+
+Page({
+  data: {
+    orderId: null,
+    customerId: null,
+    statusName: '',
+    orderDetail: {},
+    images: [], // 存储已选图片的临时路径
+    records: [],
+    serviceList: [], // 服务
+    custormList: [], // 客户
+    formObj: {
+      checkUserName: app.globalData.g_lgName,
+      checkUserId: app.globalData.g_userId,
+      checkDate: util.getRealToday(),
+      contactId: '',
+      orderId: null,
+      telephone: '',
+    },
+    receiverShow: false,
+    r_txt_Show: false,
+    allDisabled: true, //有客户下拉时临时用来控制其他下拉不显示
+    receiverChoose: 'true',
+  },
+
+  onLoad(options) {
+    const id = options.id
+    this.setData({
+      orderId: id,
+      ['formObj.checkUserName']: app.globalData.g_lgName,
+      ['formObj.checkUserId']: app.globalData.g_userId,
+    })
+    console.log(app.globalData.g_lgName, 'app.globalData.g_lgName')
+    this.getDetail()
+    this.getinstallerList()
+    console.log(util.getToday(), 'util.getToday()')
+  },
+
+  // 获取服务工单基本信息 和 工单记录进度
+  getDetail() {
+    var send_data = [
+      {
+        name: 'getInstallationOrderById',
+        returntype: 'Map',
+        parammaps: { id: this.data.orderId },
+      },
+      {
+        name: 'getInstallationDailyDetailByOrderId',
+        returntype: 'Map',
+        parammaps: { orderId: this.data.orderId },
+      },
+    ]
+    util.getDataByNames(send_data, this.handleDetail)
+  },
+
+  handleDetail(res) {
+    console.log(res, '详情页')
+    var data = res.data
+    if (data.getInstallationDailyDetailByOrderId.list != null) {
+      this.setData({
+        records: data.getInstallationDailyDetailByOrderId.list,
+        orderDetail: data.getInstallationOrderById.list[0],
+        customerId: data.getInstallationOrderById.list[0].customerId,
+        statusName: data.getInstallationOrderById.list[0].statusName,
+      })
+    } else {
+      this.setData({
+        records: [],
+        orderDetail: data.getInstallationOrderById.list[0],
+        customerId: data.getInstallationOrderById.list[0].customerId,
+        statusName: '',
+      })
+    }
+    this.getCustormList()
+  },
+
+  // 服务人员
+  getinstallerList() {
+    var send_data = [
+      {
+        name: 'getUsersSelect',
+        offset: 0,
+        pagecount: 0,
+        parammaps: {
+          enable: '1',
+        },
+      },
+    ]
+    util.getDataByNames(send_data, this.handleInstallerList)
+  },
+  handleInstallerList(res) {
+    if (res.data.getUsersSelect) {
+      this.setData({
+        serviceList: res.data.getUsersSelect.list,
+      })
+    }
+  },
+  // 客户对接
+  getCustormList() {
+    var send_data = {
+      name: 'getContacts',
+      returntype: 'Map',
+      parammaps: { customerId: this.data.customerId },
+    }
+    util.getDataByName(send_data, this.handleCustormList)
+  },
+  handleCustormList(res) {
+    console.log(res, 'res')
+    if (res.data.list) {
+      this.setData({
+        custormList: res.data.list,
+      })
+    }
+  },
+  onSelectCustorm(event) {
+    this.setData({
+      ['formObj.contactName']: this.data.custormList[event.detail.value].contactName,
+      ['formObj.contactId']: this.data.custormList[event.detail.value].id,
+    })
+  },
+
+  onDateChange(e) {
+    this.setData({
+      'formObj.checkDate': e.detail.value,
+    })
+  },
+  onSelectPerson(e) {
+    this.setData({
+      ['formObj.checkUserName']: this.data.serviceList[e.detail.value].name,
+      ['formObj.checkUserId']: this.data.serviceList[e.detail.value].id,
+    })
+  },
+  viewHistory() {
+    var id = this.data.orderId
+    wx.navigateTo({
+      url: `/pages/workbench/historyFill/historyFill?id=${id}`,
+    })
+  },
+
+  validateForm() {
+    const { checkUserName, checkDate, contactId, telephone } = this.data.formObj
+    const { images } = this.data
+    if (!checkUserName) {
+      wx.showToast({ title: '请填写服务人员', icon: 'none' })
+      return false
+    }
+    if (!checkDate) {
+      wx.showToast({ title: '请选择验收日期', icon: 'none' })
+      return false
+    }
+    if (images.length === 0) {
+      wx.showToast({ title: '请先选择图片', icon: 'none' })
+      return
+    }
+    if (!contactId) {
+      wx.showToast({ title: '请输入客户对接人', icon: 'none' })
+      return false
+    }
+    if (!telephone) {
+      wx.showToast({ title: '请输入电话号码', icon: 'none' })
+      return
+    }
+    // 手机号格式校验
+    const phoneRegex = /^1[3-9]\d{9}$/ // 正则表达式
+    if (!phoneRegex.test(telephone)) {
+      wx.showToast({ title: '请输入正确的手机号', icon: 'none' })
+      return
+    }
+    return true
+  },
+
+  goBack() {
+    wx.navigateBack()
+  },
+
+  // 删除图片
+  deleteImage(e) {
+    const index = e.currentTarget.dataset.index
+    const images = this.data.images.filter((_, i) => i !== index)
+    this.setData({ images })
+  },
+
+  // 预览图片
+  previewImage(e) {
+    const index = e.currentTarget.dataset.index
+    wx.previewImage({
+      current: this.data.images[index].tempFilePath,
+      urls: [this.data.images[index].tempFilePath],
+    })
+  },
+  // 选择图片
+  chooseImage() {
+    const remaining = 3 - this.data.images.length
+    wx.chooseMedia({
+      count: remaining,
+      sizeType: ['compressed'],
+      sourceType: ['album', 'camera'],
+      success: (res) => {
+        const newImages = res.tempFiles.map((item) => ({
+          tempFilePath: item.tempFilePath,
+          progress: 0,
+          index: this.data.images.length,
+          imageType: 'check_image',
+        }))
+        this.setData({
+          images: this.data.images.concat(newImages),
+        })
+        this.uploadImages(newImages[0])
+      },
+    })
+  },
+
+  // 上传图片到服务器
+  uploadImages(image) {
+    // 逐个上传
+    const index = image.index
+    const uploadTasks = wx.uploadFile({
+      url: app.globalData.g_url + 'authdata/uploaderimage',
+      filePath: image.tempFilePath,
+      name: 'file',
+      header: {
+        optname: 'insertcustompic',
+        id: 1,
+        token: app.globalData.g_token,
+      },
+      formData: {
+        optname: 'insertcustompic',
+        id: 1,
+        token: app.globalData.g_token,
+      },
+      success: (res) => {
+        if (res.statusCode === 200) {
+          var data = JSON.parse(res.data)
+          console.log(this.data.images, '图片上传成功', '111')
+          this.data.images[index].imageId = data.execresult.LastInsertId
+        } else {
+          wx.showToast({ title: '图片上传失败', icon: 'none' })
+        }
+        console.log(this.data.images, '图片上传成功', '111')
+      },
+      fail: () => {
+        wx.showToast({ title: '图片上传失败', icon: 'none' })
+      },
+    })
+
+    // 监听上传进度
+    uploadTasks.onProgressUpdate((res) => {
+      this.setData({
+        [`images[${index}].progress`]: res.progress,
+      })
+    })
+  },
+
+  formSubmit(e) {
+    if (!this.validateForm()) return
+    this.data.formObj.orderId = this.data.orderId
+    console.log(this.data.formObj, 'this.data.formObj')
+    this.uploadForm()
+  },
+  // 验收表单上传
+  uploadForm() {
+    var send_data = {
+      common: {
+        returnmap: '0',
+      },
+      data: [
+        {
+          name: 'insertInstallationOrderImages',
+          resultmaps: { list: this.data.images },
+          children: [
+            {
+              name: 'insertInstallationOrderImages',
+              type: 'e',
+              parammaps: {
+                orderId: this.data.orderId,
+                imageId: '@insertInstallationOrderImages.imageId',
+                imageType: '@insertInstallationOrderImages.imageType',
+              },
+            },
+          ],
+        },
+        {
+          name: 'insertInstallationOrderProcessLog',
+          type: 'e',
+          parammaps: {
+            orderId: this.data.orderId,
+            operationType: 'check',
+            operationUserId: app.globalData.g_userId,
+            operationUserName: app.globalData.g_lgName,
+            beforeStatus: this.data.statusName,
+            afterStatus: '已完成',
+            operationContent: '验收服务工单',
+          },
+        },
+        {
+          name: 'checkInstallationOrder',
+          type: 'e',
+          parammaps: {
+            orderId: this.data.formObj.orderId,
+            checkUserId: this.data.formObj.checkUserId,
+            checkUserName: this.data.formObj.checkUserName,
+            contactId:
+              this.data.receiverChoose == 'false'
+                ? '@insertContacts.LastInsertId'
+                : this.data.formObj.contactId,
+            checkDate: this.data.formObj.checkDate,
+          },
+        },
+      ],
+    }
+    // 如果对接人从下拉框中选择,则直接走之前的功能,
+    // 如果对接人是新增的 则需要创建一下
+
+    if (this.data.receiverChoose == 'false') {
+      send_data.data.unshift({
+        name: 'insertContacts',
+        type: 'e',
+        parammaps: {
+          customerId: this.data.customerId, // 客户id
+          contactName: this.data.formObj.contactName, // 联系人
+          telephone: this.data.formObj.telephone, // 客户电话
+        },
+      })
+    }
+
+    console.log('send_data:', send_data)
+    util.execDataByConfig(send_data, this.handleuploadForm)
+  },
+
+  handleuploadForm(res) {
+    if (res.msg !== 'fail') {
+      wx.showToast({
+        title: '验收提交成功',
+        icon: 'success',
+        duration: 3000,
+        success: function () {
+          setTimeout(function () {
+            // wx.navigateBack()
+            wx.redirectTo({ url: '../serviceTicket/serviceTicket' })
+          }, 1000)
+        },
+      })
+      //  wx.navigateBack();
+    } else {
+      wx.showToast({
+        title: '验收提交失败' + res.data,
+        icon: 'error',
+        duration: 4000,
+      })
+    }
+  },
+
+  //接待人文本框输入
+  change_receiver_input: function (e) {
+    var value = e.detail.value
+    var customerId = this.data.customerId
+    console.log(value)
+    //接待人列表框
+    util.getDataByName(
+      { name: 'getContacts', parammaps: { customerId: customerId } },
+      this.getPickerList2,
+    )
+  },
+
+  getPickerList2: function (res) {
+    console.log('接待人下拉数据======>', res.data.list)
+    var custormList = res.data.list
+    this.setData({
+      receiverShow: true,
+      allDisabled: false,
+      custormList: custormList,
+    })
+    if (custormList !== null) {
+      this.setData({ r_txt_Show: false })
+    } else {
+      this.setData({ r_txt_Show: true })
+    }
+  },
+  // 电话填写
+  onPhoneChange: function (e) {
+    console.log('onPhoneChange', e)
+    this.setData({
+      ['formObj.telephone']: e.detail.value,
+    })
+  },
+  //接待人完成
+  confirm_receiver_input: function (e) {
+    console.log('接收人直接输入', e)
+    this.setData({
+      receiverShow: false,
+      allDisabled: true,
+      receiverChoose: 'false',
+      ['formObj.contactName']: e.detail.value,
+    })
+  },
+  //下拉框:接待人
+  change_receiver: function (e) {
+    console.log('receiver的选项', e.detail.value)
+    var newId = this.data.custormList[e.detail.value]['id']
+    this.setData({
+      receiverIndex: e.detail.value,
+      ['formObj.contactId']: newId,
+      ['formObj.contactName']: this.data.custormList[e.detail.value].contactName,
+      receiverShow: false,
+    })
+  },
+
+  //接待人列表点击
+  on_rece_tap: function (e) {
+    console.log('接待人列表点击')
+    var newId = e.currentTarget.dataset.id
+    var name = e.currentTarget.dataset.name
+    var that = this
+
+    that.setData({
+      receiverShow: false,
+      allDisabled: true,
+      ['formObj.contactName']: name,
+      ['formObj.contactId']: newId,
+      receiverChoose: 'true',
+    })
+    //获取电话
+    util.getDataByName(
+      { name: 'getTelById', returntype: 'Map', parammaps: { id: newId } },
+      function (e) {
+        console.log(e)
+        var telephone = e.data.list[0].telephone
+        that.setData({
+          ['formObj.telephone']: telephone,
+        })
+      },
+    )
+  },
+})

+ 3 - 0
pages/workbench/acceptFill/acceptFill.json

@@ -0,0 +1,3 @@
+{
+ "navigationBarTitleText": "验收填写"
+}

+ 151 - 0
pages/workbench/acceptFill/acceptFill.wxml

@@ -0,0 +1,151 @@
+<view class="container">
+
+  <view class="service-order">
+    <view class="section-title1">服务工单</view>
+    <view class="order-info">
+      <view class="info-item">
+        <text class="label">服务单号:</text>
+        <text class="value">{{orderDetail.orderNo}}</text>
+      </view>
+     
+      <view class="info-item">
+        <text class="label">客户:</text>
+        <text class="value">{{orderDetail.customerName}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">服务人员:</text>
+        <text class="value">{{orderDetail.serviceStaffNames}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">预计服务完成时间:</text>
+        <text class="value">{{orderDetail.estimatedCompleteTime}}</text>
+      </view>
+      <view class="info-item delay-info">
+        <text class="label">距服务完成时间还剩:</text>
+        <text class="value highlight">{{orderDetail.remainingTime}}天</text>
+      </view>
+      <view class="info-item">
+        <text class="label">备注:</text>
+        <text class="value">{{orderDetail.remark}}</text>
+      </view>
+    </view>
+  </view>
+ 
+
+ <view class="service-record">
+    <view class="record-header"> 
+      <text class="section-title">验收填写</text>
+      <l-button class="history-btn" bindtap="viewHistory" size="mini">服务记录</l-button>
+    </view>
+  </view>
+  <view class="record-content" >
+    <view class="form-container">
+      <form catchsubmit="formSubmit" >
+      <view class="form-item">
+        <text class="form-label required">服务人员:</text>
+          <picker class="picker" mode="selector" range-key="name"  range="{{serviceList}}" bindchange="onSelectPerson">
+          <view class="picker-text">{{formObj.checkUserName || "请选择服务人员"}}</view>
+        </picker>
+      </view>
+     <view class="form-item">
+        <text class="form-label required">验收日期:</text>
+        <picker class="picker" mode="date" bindchange="onDateChange" value="{{formObj.checkDate}}">
+          <view class="picker-text">{{formObj.checkDate || "请选择验收日期"}}</view>
+        </picker>
+      </view>
+      <view class="form-item">
+        <text class="form-label required">客户对接人:</text>
+         <l-input class='input-custorm' id="receiverName" value="{{formObj.contactName}}" hide-label show-row="{{false}}" bind:lininput="change_receiver_input" bind:linconfirm="confirm_receiver_input" bind:linblur="confirm_receiver_input" clear="{{true}}" placeholder="请输入客户对接人"/>
+     
+      </view>
+       <scroll-view class="receiver_bx" scroll-y="true" wx:if="{{receiverShow}}" style = "top:580rpx;">
+        <view  class = "receiver_txt" wx:if="{{r_txt_Show}}">暂无内容</view>
+        <block wx:for="{{custormList}}" wx:for-item="item"  wx:key="index">
+            <view class = "receiver_txt" bindtap="on_rece_tap" data-id="{{item.id}}" data-name="{{item.name}}"> {{item.name}} </view>
+        </block>
+    </scroll-view>
+     <view class="form-item">
+        <text class="form-label required">对接人电话:</text>
+         <l-input class='input-custorm'  bind:lininput="onPhoneChange"  id="receiverTel" value="{{formObj.telephone}}" hide-label show-row="{{false}}" placeholder="请输入对接人电话"/>
+      </view>
+
+      <view class="form-item">
+        <text class="form-label required">验收单:</text>
+        <view class="uploader">
+          <view class="preview-list">
+            <block wx:for="{{images}}" wx:key="index">
+              <view class="preview-item">
+                <image 
+                  class="preview-image" 
+                  src="{{item.tempFilePath}}" 
+                  mode="aspectFill"
+                  bindtap="previewImage"
+                  data-index="{{index}}"
+                />
+                 <view class="delete-btn" bindtap="deleteImage" data-index="{{index}}">×</view>
+              </view>
+            </block>
+            <view 
+              class="preview-item upload-btn" 
+              wx:if="{{images.length < 3}}"
+              bindtap="chooseImage"
+            >
+              <view class="add-text">+</view>
+          </view>
+        </view>
+        </view>
+      </view>
+
+      <view class="btn-area">
+        <button class="medium-button"  style="margin: 30rpx 0"  bindtap="goBack" data-id="{{item.id}}">取消</button>
+        <button class="medium-button"  style="margin: 30rpx 0; background-color: #3963bc; color: white;" formType="submit">提交</button>
+      </view>
+       </form>
+    </view>
+  </view>
+
+  <!-- <view class="service-record">
+     <view class="record-header"> 
+      <text class="section-title">服务记录</text>
+      <l-button  wx:if="{{records && records.length>0}}" class="history-btn" bindtap="viewHistory" size="mini">历史记录</l-button>
+    </view>
+     <view  wx:if="{{ records && records.length<1 }}" class="info-item nodata">暂无记录</view>
+  </view>
+   <view>
+    <view class="order-info item-box" wx:for="{{records}}" wx:key="index" >
+      <view class="info-item">
+        <text class="label">日期:</text>
+        <text class="value">{{item.installDate}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">货品:</text>
+        <text class="value">{{item.goodsName}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">数量:</text>
+        <text class="value">{{item.orderQuantity}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">剩余量:</text>
+        <text class="value">{{item.unshippedQuantity}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">已完成量:</text>
+        <text class="value">{{item.shippedQuantity}}</text>
+      </view>
+      <view class="info-item delay-info">
+        <text class="label">今日完成量:</text>
+        <text class="value highlight">{{item.installQuantity}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">备注:</text>
+        <text class="value">{{item.installRemark}}</text>
+      </view>
+    </view>
+  </view> -->
+
+ 
+   
+
+   
+</view>

+ 225 - 0
pages/workbench/acceptFill/acceptFill.wxss

@@ -0,0 +1,225 @@
+.container {
+  padding: 20rpx;
+  min-height: 100vh;
+}
+
+.section-title {
+  color: #333 !important;
+  font-size: 32rpx;
+  padding: 20rpx;
+  font-weight: bold;
+}
+.section-title1 {
+  color: #333 !important;
+  font-size: 32rpx;
+  font-weight: bold;
+  padding: 20rpx;
+  border-bottom: 1px solid #eee;
+}
+
+.service-order {
+  background: #fff;
+  margin-bottom: 20rpx;
+}
+.order-info {
+  padding: 10rpx 20rpx;
+  background: #fff;
+  margin-bottom: 10rpx;
+}
+.info-item {
+  margin-bottom: 20rpx;
+  font-size: 28rpx;
+}
+
+.delay-info {
+  color: #ff4d4f;
+}
+
+.highlight {
+  color: #ff4d4f;
+}
+
+.service-record {
+  background: #fff;
+}
+
+.record-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-right: 20rpx;
+  border-bottom: 1px solid #eee;
+}
+
+.history-btn {
+  color: #3963bc;
+  font-size: 28rpx;
+}
+
+.record-content {
+  padding: 20rpx;
+  background-color: #fff;
+  margin-bottom: 20rpx;
+}
+
+.product-item {
+  margin-bottom: 10rpx;
+}
+
+.product-label {
+  display: inline-block;
+  width: 180rpx;
+  font-size: 28rpx;
+}
+
+.product-name,
+.product-value {
+  color: #333;
+}
+.quantity-input {
+  display: inline-block;
+  width: 100px;
+  border: 1px solid #ddd;
+  padding: 4px 8px;
+  border-radius: 4px;
+  font-size: 28rpx;
+  height: 20rpx;
+  color: #333;
+}
+
+.form-container {
+  padding: 20rpx;
+}
+
+.form-item {
+  margin-bottom: 10rpx;
+  display: flex;
+  justify-content: left;
+  align-items: start;
+}
+
+.form-label {
+  width: 200rpx;
+  font-size: 30rpx;
+  color: #333;
+}
+
+.form-input {
+  flex: 1;
+  height: 60rpx;
+  border: 1rpx solid #ddd;
+  border-radius: 8rpx;
+  padding: 10rpx;
+}
+
+.picker {
+  flex: 1;
+  height: 60rpx;
+  border: 1rpx solid #ddd;
+  border-radius: 8rpx;
+  padding: 10rpx;
+}
+
+.picker-text {
+  line-height: 60rpx;
+  color: #333;
+}
+
+.button-container {
+  display: flex;
+  justify-content: center;
+}
+
+.nodata {
+  padding: 20rpx;
+  text-align: center;
+  color: #999;
+}
+
+.medium-button {
+  padding: 0px 20px;
+  border: none;
+  border-radius: 4px;
+  cursor: pointer;
+  font-size: 28rpx;
+}
+.btn-area {
+  display: flex;
+  justify-content: space-around;
+}
+
+.required::before {
+  content: '*';
+  color: red;
+  margin-right: 5rpx;
+}
+
+.uploader {
+  margin-top: 20rpx;
+}
+
+.preview-list {
+  display: flex;
+  flex-wrap: wrap;
+}
+
+.preview-item {
+  width: 200rpx;
+  height: 200rpx;
+  margin-right: 20rpx;
+  margin-bottom: 20rpx;
+  position: relative;
+}
+
+.preview-image {
+  width: 100%;
+  height: 100%;
+  border-radius: 8rpx;
+}
+
+.upload-btn {
+  border: 2rpx dashed #ccc;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background-color: #f5f5f5;
+}
+
+.add-text {
+  font-size: 60rpx;
+  color: #666;
+}
+
+.delete-btn {
+  position: absolute;
+  right: -10rpx;
+  top: -10rpx;
+  width: 40rpx;
+  height: 40rpx;
+  background: #ff4444;
+  border-radius: 50%;
+  color: white;
+  text-align: center;
+  line-height: 40rpx;
+  font-size: 36rpx;
+  z-index: 2;
+}
+
+.action-buttons {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  display: flex;
+  justify-content: space-between;
+  padding: 10rpx;
+}
+
+.input-custorm {
+  flex: 1;
+  height: 60rpx;
+  border: 1rpx solid #ddd;
+  border-radius: 8rpx;
+  padding-bottom: 30rpx;
+  position: relative;
+}

+ 302 - 0
pages/workbench/dailyFill/dailyFill.js

@@ -0,0 +1,302 @@
+var util = require('../../../utils/util.js')
+const app = getApp()
+
+Page({
+  data: {
+    orderId: null,
+    selectedDate: {},
+    selectedDateArray: [],
+    datas: [],
+    customerId: null,
+    orderDetail: {},
+    records: [],
+  },
+
+  onLoad(options) {
+    const id = options.id
+    this.setData({
+      orderId: id,
+    })
+    this.initdatas()
+    this.getDetail()
+    this.getDailyFillList()
+  },
+
+  // 获取服务工单基本信息 和 工单记录进度
+  getDetail() {
+    var send_data = [
+      { name: 'getInstallationOrderById', returntype: 'Map', parammaps: { id: this.data.orderId } },
+    ]
+    util.getDataByNames(send_data, this.handleDetail)
+  },
+  handleDetail(res) {
+    var data = res.data
+    this.setData({
+      orderDetail: data.getInstallationOrderById.list[0],
+      customerId: data.getInstallationOrderById.list[0].customerId,
+    })
+  },
+
+  // 初始化日期数组
+  initdatas: function () {
+    const dates = []
+    const today = new Date()
+    // 添加今天和前两天的日期
+    for (let i = 0; i < 3; i++) {
+      const date = new Date(today)
+      date.setDate(today.getDate() - i)
+      const formatDate = this.formatDate(date)
+      dates.push(formatDate)
+    }
+    this.setData({
+      datas: dates,
+      selectedDates: { [dates[0]]: true }, // 默认选中今天
+      selectedDateArray: [dates[0]],
+    })
+  },
+  // 格式化日期为 YYYY-MM-DD
+  formatDate: function (date) {
+    const year = date.getFullYear()
+    const month = (date.getMonth() + 1).toString().padStart(2, '0')
+    const day = date.getDate().toString().padStart(2, '0')
+    return `${year}-${month}-${day}`
+  },
+  // 日期选择
+  selectDate(e) {
+    const date = e.currentTarget.dataset.date
+    const selectedDates = { ...this.data.selectedDates }
+    let selectedDateArray = [...this.data.selectedDateArray]
+    // 切换选中状态
+    if (selectedDates[date]) {
+      // 如果当前只有一个选中的日期,不允许取消
+      if (selectedDateArray.length === 1) {
+        wx.showToast({
+          title: '至少需要选择一个日期',
+          icon: 'none',
+        })
+        return
+      }
+      delete selectedDates[date]
+      selectedDateArray = selectedDateArray.filter((item) => item !== date)
+    } else {
+      selectedDates[date] = true
+      selectedDateArray.push(date)
+    }
+    this.setData({
+      selectedDates: selectedDates,
+      selectedDateArray: selectedDateArray,
+    })
+    console.log(selectedDateArray, 'selectedDates')
+    this.getDailyFillList()
+  },
+  getDailyFillList() {
+    var send_data = [
+      {
+        name: 'getInstallationDailyData',
+        returntype: 'Map',
+        parammaps: { orderId: this.data.orderId, dates: this.data.selectedDateArray.join(',') },
+      },
+    ]
+    util.getDataByNames(send_data, this.handleDailyFill)
+  },
+  handleDailyFill(res) {
+    if (res.data.getInstallationDailyData.list) {
+      res.data.getInstallationDailyData.list.map((item) => {
+        item.installDate = ''
+        item.todayQuantity = 0
+        item.remark = ''
+      })
+      this.setData({
+        records: res.data.getInstallationDailyData.list,
+      })
+    } else {
+      this.setData({
+        records: [],
+      })
+    }
+  },
+  onRemarkChange(e) {
+    var index = e.target.dataset.index
+    let records = this.data.records
+    records[index].remark = e.detail.value
+    this.setData({
+      records: records,
+    })
+    console.log(this.data.records, 'remark')
+  },
+  onQuantityChange(e) {
+    console.log(e, 'ee')
+    var index = e.target.dataset.index
+    let records = this.data.records
+    records[index].todayQuantity = e.detail.value
+    this.setData({
+      records: records,
+    })
+    console.log(this.data.records, '数量')
+  },
+
+  // 提交每日填写
+  posttDailyFill() {
+    // 检查每条记录的必填项
+
+    for (let i = 0; i < this.data.records.length; i++) {
+      const record = this.data.records[i]
+      record.installDate = record.date
+      if (record.todayQuantity < 0) {
+        wx.showToast({
+          title: '请正确填写今日完成量',
+          icon: 'none',
+        })
+        return
+      }
+      if (record.remark == '' || !record.remark) {
+        wx.showToast({
+          title: '请填写备注',
+          icon: 'none',
+        })
+        return
+      }
+    }
+    console.log(this.data.records, 'this.data.records')
+
+    var send_data = {
+      common: { returnmap: '0' },
+      data: [
+        {
+          name: 'deleteInstallationDailyWriteByDates',
+          type: 'e',
+          parammaps: {
+            datas: this.data.selectedDateArray.join(','),
+            userId: app.globalData.g_userId,
+            orderId: this.data.orderId,
+          },
+        },
+        {
+          name: 'submitInstallationDailyWrite',
+          resultmaps: {
+            list: this.data.records,
+          },
+          children: [
+            {
+              name: 'insertInstallationDailyWrite',
+              type: 'e',
+              parammaps: {
+                orderId: this.data.orderId,
+                installUserId: app.globalData.g_userId,
+                installUserName: app.globalData.g_lgName,
+                goodsName: '@submitInstallationDailyWrite.goodsName',
+                installDate: '@submitInstallationDailyWrite.installDate',
+                goodsId: '@submitInstallationDailyWrite.goodsId',
+                todayQuantity: '@submitInstallationDailyWrite.todayQuantity',
+                remark: '@submitInstallationDailyWrite.remark',
+                projectId: '@submitInstallationDailyWrite.projectId',
+                projectName: '@submitInstallationDailyWrite.projectName',
+              },
+            },
+          ],
+        },
+        {
+          name: 'refreshInstallationOrderDetailQuantity',
+          type: 'e',
+          parammaps: {
+            orderId: this.data.orderId,
+          },
+        },
+        {
+          name: 'refreshInstallationOrderProcessByOrderId',
+          type: 'e',
+          parammaps: {
+            orderId: this.data.orderId,
+          },
+        },
+        {
+          name: 'insertInstallationOrderProcessLog',
+          type: 'e',
+          parammaps: {
+            orderId: this.data.orderId,
+            operationType: 'write',
+            operationUserId: app.globalData.g_userId,
+            operationUserName: app.globalData.g_lgName,
+            beforeStatus: '处理中',
+            afterStatus: '处理中',
+            operationContent: '',
+          },
+        },
+        {
+          name: 'updateDailyDetailYesterdayAndBeforeQuantity',
+          type: 'e',
+          parammaps: {
+            orderId: this.data.orderId,
+          },
+        },
+      ],
+    }
+    util.execDataByConfig(send_data, this.handleAccept)
+  },
+
+  handleAccept: function (res) {
+    console.log(res, 'res')
+    if (res.msg !== 'fail') {
+      wx.showToast({
+        title: '保存成功',
+        icon: 'success',
+        duration: 3000,
+        success: function () {
+          // wx.redirectTo() 会关闭当前页面,返回时不会刷新
+          // wx.navigateBack() 返回上一页时会触发onShow生命周期,可以在onShow中刷新数据
+          setTimeout(function () {
+            // wx.navigateBack()
+            wx.redirectTo({ url: '../serviceTicket/serviceTicket' })
+          }, 1000)
+        },
+      })
+    } else {
+      wx.showToast({
+        title: '保存失败' + res.data,
+        icon: 'error',
+        duration: 2000,
+      })
+    }
+  },
+  handleReject() {
+    wx.navigateBack()
+  },
+
+  goBack() {
+    wx.navigateBack()
+  },
+  viewHistory() {
+    var id = this.data.orderId
+    wx.navigateTo({
+      url: `/pages/workbench/historyFill/historyFill?id=${id}`,
+    })
+  },
+
+  // 更新今日完成量
+  updateTodayQuantity(e) {
+    const value = parseInt(e.detail.value) || 0
+    const remaining = this.data.totalQuantity - this.data.completedQuantity - value
+
+    this.setData({
+      todayQuantity: value,
+      remainingQuantity: remaining >= 0 ? remaining : 0,
+    })
+  },
+
+  // 保存记录
+  saveRecord() {
+    wx.showLoading({
+      title: '保存中...',
+    })
+
+    // 这里添加保存逻辑
+
+    setTimeout(() => {
+      wx.hideLoading()
+      wx.showToast({
+        title: '保存成功',
+        icon: 'success',
+      })
+    }, 1500)
+  },
+})

+ 6 - 0
pages/workbench/dailyFill/dailyFill.json

@@ -0,0 +1,6 @@
+{
+ "navigationBarTitleText": "每日填写",
+  "usingComponents": {
+    "l-icon": "/miniprogram_npm/lin-ui/icon/index"
+  }
+}

+ 105 - 0
pages/workbench/dailyFill/dailyFill.wxml

@@ -0,0 +1,105 @@
+<view class="container">
+
+  <view class="service-order">
+    <view class="section-title1">服务工单</view>
+      <view class="order-info">
+      <view class="info-item">
+        <text class="label">服务单号:</text>
+        <text class="value">{{orderDetail.orderNo}}</text>
+      </view>
+      <!-- <view class="info-item">
+        <text class="label">服务项目:</text>
+        <text class="value">{{orderDetail.projectName}}</text>
+      </view> -->
+      <view class="info-item">
+        <text class="label">客户:</text>
+        <text class="value">{{orderDetail.customerName}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">服务人员:</text>
+        <text class="value">{{orderDetail.serviceStaffNames}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">预计服务完成时间:</text>
+        <text class="value">{{orderDetail.estimatedCompleteTime}}</text>
+      </view>
+      <view class="info-item delay-info">
+        <text class="label">距服务完成时间还剩:</text>
+        <text class="value highlight">{{orderDetail.remainingTime}}天</text>
+      </view>
+      <view class="info-item">
+        <text class="label">备注:</text>
+        <text class="value">{{orderDetail.remark}}</text>
+      </view>
+    </view>
+  </view>
+
+ 
+  <view class="service-record">
+     <view class="record-header"> 
+      <text class="section-title">每日填写</text>
+      <l-button class="history-btn" bindtap="viewHistory" size="mini">服务记录</l-button>
+    </view>
+  </view>
+  <!-- 添加日期选择器 -->
+  <view class="date-picker">
+    <view class="date-item {{selectedDates[date] ? 'selected' : ''}}" 
+        wx:for="{{datas}}" 
+        wx:for-item="date" 
+        wx:key="index"
+        bindtap="selectDate"
+        data-date="{{date}}">
+    <text class="date-text">{{date}}</text>
+  </view>
+  </view>
+
+
+  <view class="record-content"  wx:for="{{records}}" wx:key="index">
+      <view class="product-info">
+        <view class="product-item">
+         <text class="product-label">日期:</text>
+         <text class="product-name">{{item.date}}</text>
+        </view>
+         <view class="product-item">
+          <text class="product-label">服务项目:</text>
+          <text class="product-name">{{item.projectName}}</text>
+        </view>
+         <!-- <view class="product-item">
+          <text class="product-label">货品编号:</text>
+          <text class="product-name">{{item.goodsCode}}</text>
+        </view> -->
+        <view class="product-item">
+          <text class="product-label">货品:</text>
+          <text class="product-name">{{item.goodsName}}</text>
+        </view>
+        <view class="product-item">
+          <text class="product-label">数量:</text>
+          <text class="product-value">{{item.orderQuantity}}</text>
+        </view>
+         <view class="product-item">
+          <text class="product-label">剩余量:</text>
+          <text class="product-value">{{item.unshippedQuantity}}</text>
+        </view>
+        <view class="product-item">
+          <text class="product-label">已完成量:</text>
+          <text class="product-value">{{item.shippedQuantity}}</text>
+        </view>
+      
+        <view class="product-item">
+          <text class="product-label">今日完成量:</text>
+          <input class="quantity-input" type="number" value="{{item.todayQuantity ?item.todayQuantity:''}}" data-index="{{index}}" bindinput="onQuantityChange"  placeholder-style="font-size:28rpx;color:#aaa" placeholder="请填写今日完成量" />
+        </view>
+  
+        <view class="product-item">
+          <text class="product-label required">备注:</text>
+          <textarea class="remarks-input" value="{{item.remark}}" bindinput="onRemarkChange"  data-index="{{index}}" placeholder-style="font-size:28rpx;color:#aaa"  placeholder="备注提示:是否使用临时工(公司支付工人工资),如有则填写工人数量,如没有填写无,请如实填写,否则将影响你的绩效" />
+        </view>
+      </view>
+  </view>
+
+   <!-- 底部按钮 -->
+    <view class="ticket-actions" >
+      <l-button size="mini" type="default" plain="{{true}}" bindtap="handleReject" data-id="{{item.id}}">取消</l-button>
+      <l-button size="mini" type="default"  bindtap="posttDailyFill" data-id="{{item.id}}">保存</l-button>
+    </view>
+</view>

+ 157 - 0
pages/workbench/dailyFill/dailyFill.wxss

@@ -0,0 +1,157 @@
+.container {
+  padding: 20rpx;
+  min-height: 100vh;
+}
+
+.section-title {
+  color: #333 !important;
+  font-size: 32rpx;
+  padding: 20rpx;
+  font-weight: bold;
+}
+.section-title1 {
+  color: #333 !important;
+  font-size: 32rpx;
+  font-weight: bold;
+  padding: 20rpx;
+  border-bottom: 1px solid #eee;
+}
+
+.service-order {
+  background: #fff;
+  margin-bottom: 20rpx;
+}
+.order-info {
+  padding: 20rpx;
+}
+.info-item {
+  margin-bottom: 20rpx;
+}
+.info-item > text {
+  font-size: 32rpx;
+}
+.product-item > text {
+  font-size: 32rpx;
+}
+.delay-info {
+  color: #ff4d4f;
+}
+
+.highlight {
+  color: #ff4d4f;
+}
+
+.service-record {
+  background: #fff;
+}
+
+.record-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-right: 20rpx;
+  border-bottom: 1px solid #eee;
+}
+
+.history-btn {
+  color: #73c7ff;
+  font-size: 28rpx;
+}
+
+.record-content {
+  padding: 20rpx;
+  background-color: #fff;
+  margin-bottom: 20rpx;
+}
+
+.product-item {
+  margin-bottom: 20rpx;
+}
+
+.product-label {
+  display: inline-block;
+  width: 200rpx;
+  font-size: 32rpx;
+}
+
+.product-name,
+.product-value {
+  color: #333;
+}
+.quantity-input {
+  display: inline-block;
+  width: 58%;
+  border: 1px solid #ddd;
+  padding: 8px 8px;
+  border-radius: 4px;
+  font-size: 28rpx;
+  color: #333;
+}
+
+.remarks-input {
+  width: 64%;
+  display: inline-block;
+  border: 1px solid #ddd;
+  padding: 10rpx;
+  border-radius: 4px;
+  margin-top: 8px;
+  font-size: 34rpx;
+  color: #333;
+  min-height: 100rpx; /* 最小高度 */
+  max-height: 200rpx; /* 最小高度 */
+  box-sizing: border-box; /* 确保 padding 和 border 不影响高度计算 */
+}
+
+.ticket-actions {
+  display: flex;
+  justify-content: flex-end;
+  gap: 20rpx;
+  padding-top: 15rpx;
+  border-top: 1rpx solid #eee;
+  margin-bottom: 40rpx;
+}
+.date-picker {
+  display: flex;
+  justify-content: space-around;
+  padding: 10px;
+  background: #fff;
+  margin: 10px 0;
+}
+
+.date-item {
+  padding: 8px 15px;
+  border-radius: 20px;
+  background: #f5f5f5;
+  font-size: 24rpx;
+}
+
+.selected {
+  background: #3683d6;
+}
+.selected > text {
+  color: #fff !important;
+}
+
+.date-text {
+  font-size: 24rpx;
+}
+
+.picker {
+  flex: 1;
+  height: 50rpx;
+  border: 1rpx solid #ddd;
+  border-radius: 8rpx;
+  padding: 4rpx 32rpx;
+  display: inline-block;
+  margin-bottom: 10rpx;
+}
+
+.picker-text {
+  line-height: 50rpx;
+  color: #333;
+}
+.required::before {
+  content: '*';
+  color: red;
+  margin-right: 5rpx;
+}

+ 221 - 0
pages/workbench/historyFill/historyFill.js

@@ -0,0 +1,221 @@
+var util = require('../../../utils/util.js')
+Page({
+  data: {
+    orderId: null,
+    noData: '../../../images/noData.png',
+    dataListTips: '暂无数据',
+    // 初始日期范围
+    form: {
+      beginDate: util.get7daysAgo(),
+      endDate: util.getRealToday(),
+      orderId: null,
+      staffId: '',
+    },
+    serviceStaffname: '',
+    records: [],
+    installerList: [],
+  },
+
+  onLoad(options) {
+    const id = options.id
+    this.setData({
+      orderId: id,
+      ['form.orderId']: id,
+    })
+    this.getDetail()
+    // this.getinstallerList()
+  },
+
+  getDetail() {
+    var send_data = [
+      { name: 'getInstallationDailyDetailByOrderId', returntype: 'Map', parammaps: this.data.form },
+    ]
+    util.getDataByNames(send_data, this.handleDetail)
+  },
+
+  handleDetail(res) {
+    var data = res.data
+    if (data.getInstallationDailyDetailByOrderId.list != null) {
+      var list = data.getInstallationDailyDetailByOrderId.list
+      var service = list.map((item, indexx) => {
+        const obj = {
+          name: item.installUserName,
+          id: item.installUserId,
+        }
+        return obj
+      })
+
+      const uniqueData = service.filter((item, index, self) => {
+        return index === self.findIndex((t) => t.id === item.id)
+      })
+      console.log(uniqueData, 'service')
+      this.setData({
+        records: data.getInstallationDailyDetailByOrderId.list,
+        installerList: uniqueData,
+      })
+    } else {
+      this.setData({
+        records: [],
+      })
+    }
+  },
+  onInstallerChange: function (e) {
+    console.log(e, 'eee')
+    this.setData({
+      serviceStaffname: this.data.installerList[e.detail.value].name,
+      ['form.staffId']: this.data.installerList[e.detail.value].id,
+    })
+  },
+  onInputChangeClear(e) {
+    this.setData({
+      serviceStaffname: '',
+      ['form.staffId']: '',
+    })
+  },
+  // 服务人员
+  getinstallerList() {
+    var send_data = [
+      {
+        name: 'getUsersSelect',
+        offset: 0,
+        pagecount: 0,
+        parammaps: {
+          enable: '1',
+          orderId: this.data.orderId,
+        },
+      },
+    ]
+
+    util.getDataByNames(send_data, this.handleInstallerList)
+  },
+  handleInstallerList(res) {
+    const obj = res.data
+    if (obj.getUsersSelect) {
+      this.setData({
+        installerList: obj.getUsersSelect.list,
+      })
+    }
+  },
+
+  onStaffChange(e) {
+    this.setData({
+      serverPerson: this.data.serviceList[e.detail.value],
+    })
+  },
+
+  onContactChange(e) {
+    this.setData({
+      serverPerson: e.detail.value,
+    })
+  },
+
+  onDateChange(e) {
+    this.setData({
+      'formObj.acceptanceDate': e.detail.value,
+    })
+  },
+  onSelectPerson(event) {
+    this.setData({
+      'formObj.serverPerson': this.data.serviceList[event.detail.value],
+    })
+  },
+  onBack() {
+    wx.navigateBack()
+  },
+  uploadReceipt() {
+    // 上传验收单的逻辑
+    const that = this
+    wx.chooseImage({
+      count: 1,
+      sizeType: ['compressed'],
+      sourceType: ['album', 'camera'],
+      success(res) {
+        that.setData({
+          'formObj.acceptanceFile': res.tempFilePaths[0],
+          'errors.acceptanceFile': '',
+        })
+      },
+    })
+  },
+
+  validateForm() {
+    const { serverPerson, acceptanceDate, acceptanceFile } = this.data.formObj
+    if (!serverPerson) {
+      wx.showToast({ title: '请填写服务人员', icon: 'none' })
+      return false
+    }
+    if (!acceptanceDate) {
+      wx.showToast({ title: '请选择验收日期', icon: 'none' })
+      return false
+    }
+    if (!acceptanceFile) {
+      wx.showToast({ title: '请上传验收单', icon: 'none' })
+      return false
+    }
+    return true
+  },
+
+  formSubmit(e) {
+    console.log('this.data.formObj:', this.data.formObj)
+    wx.showToast({ title: '提交成功', icon: 'success' })
+    if (!this.validateForm()) return
+  },
+
+  formReset(e) {
+    console.log('form发生了reset事件,携带数据为:', e.detail.value)
+    this.setData({
+      chosen: '',
+    })
+  },
+
+  goBack() {
+    wx.navigateBack()
+  },
+  //日期1
+  bindDateChange1: function (e) {
+    this.setData({
+      ['form.beginDate']: e.detail.value,
+    })
+  },
+  //日期2
+  bindDateChange2: function (e) {
+    this.setData({
+      ['form.endDate']: e.detail.value,
+    })
+  },
+
+  viewHistory() {
+    // 查看历史记录
+    wx.navigateTo({
+      url: '/pages/workbench/historyRecord/historyRecord',
+    })
+  },
+
+  // 更新今日完成量
+  updateTodayQuantity(e) {
+    const value = parseInt(e.detail.value) || 0
+    const remaining = this.data.totalQuantity - this.data.completedQuantity - value
+
+    this.setData({
+      todayQuantity: value,
+      remainingQuantity: remaining >= 0 ? remaining : 0,
+    })
+  },
+
+  // 保存记录
+  saveRecord() {
+    wx.showLoading({
+      title: '保存中...',
+    })
+
+    // 这里添加保存逻辑
+
+    setTimeout(() => {
+      wx.hideLoading()
+      wx.showToast({
+        title: '保存成功',
+        icon: 'success',
+      })
+    }, 1500)
+  },
+})

+ 6 - 0
pages/workbench/historyFill/historyFill.json

@@ -0,0 +1,6 @@
+{
+ "navigationBarTitleText": "历史记录",
+  "usingComponents": {
+    "l-icon": "/miniprogram_npm/lin-ui/icon/index"
+  }
+}

+ 112 - 0
pages/workbench/historyFill/historyFill.wxml

@@ -0,0 +1,112 @@
+<view class="container">
+  <view class="date-range-picker">
+    <!-- 开始日期 -->
+    <picker 
+      mode="date" 
+      start="2015-09-01"
+      name="beginDate"
+      bindchange="bindDateChange1"
+      place
+    >
+      <view class="date-item">
+        <text class="date-value">{{form.beginDate}}</text>
+      </view>
+    </picker>
+    <!-- 分隔符 -->
+    <text class="separator">~</text>
+    <!-- 结束日期 -->
+    <picker 
+      mode="date" 
+      start="2015-09-01"
+      name="endDate"
+      bindchange="bindDateChange2"
+    >
+      <view class="date-item">
+        <text class="date-value">{{form.endDate}}</text>
+      </view>
+    </picker>
+    <!--  -->
+    
+  </view>
+  <view class="search-bar" style="display: flex; align-items: center;">
+          <picker 
+            mode="selector"
+            range="{{installerList}}" 
+            range-key="name"
+            value="{{statusIndex}}"
+            bindchange="onInstallerChange"
+            bindcancel="onInputChangeClear"
+            style="flex: 1; margin-right: 10px;"
+            class="search-input"
+          >
+            <view class="picker-view">
+              <text style="color: {{serviceStaffname ? '#333333' : '#999999'}}">{{ serviceStaffname || '请选择服务人员'}}</text>
+            </view>
+          </picker>
+           <button class="search-btn" bindtap="getDetail"  style="flex-shrink: 0;width:110rpx; font-size: 12px;margin:0; background-color: #3963bc; color: white; border: none;" >搜索</button>
+
+        </view>
+
+
+ 
+  <view class="service-record">
+     <view class="record-header"> 
+      <text class="section-title">服务记录</text>
+    </view>
+   
+  </view>
+   <view>
+    <view class="order-info item-box" wx:for="{{records}}" wx:key="index" >
+       <view class="info-item">
+        <text class="label">日期:</text>
+        <text class="value">{{item.installDate}}</text>
+      </view>
+       <view class="info-item">
+        <text class="label">服务项目:</text>
+        <text class="value">{{item.projectName}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">货品编号:</text>
+        <text class="value">{{item.goodsCode}}</text>
+      </view>
+    
+      <view class="info-item">
+        <text class="label">货品:</text>
+        <text class="value">{{item.goodsName}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">数量:</text>
+        <text class="value">{{item.orderQuantity}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">剩余量:</text>
+        <text class="value">{{item.unshippedQuantity}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">已完成量:</text>
+        <text class="value">{{item.shippedQuantity}}</text>
+      </view>
+      <view class="info-item delay-info">
+        <text class="label">今日完成量:</text>
+        <text class="value highlight">{{item.installQuantity}}</text>
+      </view>
+       <view class="info-item">
+        <text class="label">服务人员:</text>
+        <text class="value">{{item.installUserName}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">备注:</text>
+        <text class="value">{{item.installRemark}}</text>
+      </view>
+    </view>
+  </view>
+   <block wx:if="{{!records || records.length === 0}}">
+        <view class="table">
+          <image style="width: 400rpx; height: 400rpx;margin:0 auto" mode="aspectFit" src="{{noData}}"></image>
+          <text style="margin:0 auto">{{dataListTips}}</text> 
+        </view>
+    </block>
+   
+  <button class="back-btn" style="flex-shrink: 0; width:140rpx;font-size: 28rpx;margin:20rpx auto; " bindtap="onBack">返回</button>
+   
+</view>

+ 124 - 0
pages/workbench/historyFill/historyFill.wxss

@@ -0,0 +1,124 @@
+.container {
+  padding: 20rpx;
+  min-height: 100vh;
+}
+/* 日期范围选择器 */
+.date-range-picker {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  background: #fff;
+  padding: 20rpx 40rpx;
+  /* margin-bottom: 20rpx; */
+}
+
+/* 日期项 */
+.date-item {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+/* 日期标签 */
+.date-label {
+  color: #999;
+  font-size: 24rpx;
+  margin-bottom: 10rpx;
+}
+
+/* 日期值 */
+.date-value {
+  color: #333;
+  font-size: 28rpx;
+  font-weight: 500;
+}
+
+.order-info {
+  padding: 10rpx 20rpx;
+  background: #fff;
+  margin-bottom: 10rpx;
+}
+.info-item {
+  margin-bottom: 20rpx;
+  font-size: 28rpx;
+}
+
+.service-record {
+  background: #fff;
+}
+.section-title {
+  color: #333 !important;
+  font-size: 32rpx;
+  font-weight: bold;
+  padding: 20rpx;
+  border-bottom: 1px solid #eee;
+}
+
+.service-order {
+  background: #fff;
+  margin-bottom: 20rpx;
+}
+
+.record-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-right: 20rpx;
+  border-bottom: 1px solid #eee;
+}
+
+.history-btn {
+  color: #3963bc;
+  font-size: 28rpx;
+}
+
+.record-content {
+  padding: 20rpx;
+  background-color: #fff;
+  margin-bottom: 20rpx;
+}
+
+.product-item {
+  margin-bottom: 10rpx;
+}
+
+.product-label {
+  display: inline-block;
+  width: 180rpx;
+  font-size: 28rpx;
+}
+
+.product-name,
+.product-value {
+  color: #333;
+}
+
+.table {
+  background-color: #f2f2f2;
+  display: flex;
+  flex-direction: column;
+  box-sizing: border-box;
+  padding: 10rpx 20rpx;
+}
+.table_box {
+  background-color: #fff;
+  display: inline-block;
+  border-radius: 10rpx;
+  width: 96%;
+  margin-bottom: 20rpx;
+  padding: 20rpx;
+  position: relative;
+}
+.search-input {
+  height: 60rpx;
+  line-height: 60rpx;
+  text-align: center;
+}
+
+.info-item > text {
+  font-size: 32rpx;
+}
+.product-item > text {
+  font-size: 32rpx;
+}

+ 67 - 0
pages/workbench/serviceOrderDetail/serviceOrderDetail.js

@@ -0,0 +1,67 @@
+
+var util = require('../../../utils/util.js')
+Page({
+  data: {
+    orderId:null,
+    detailObj: {},
+    goodsList:[]
+  },
+
+  onLoad(options) {
+    const id = options.id;
+    this.setData({
+      orderId: id
+    });
+    this.getDetail()
+  },
+
+  getDetail() {
+    var send_data = [
+      { "name": "getInstallationOrderById", "returntype": "Map", "parammaps": { "id": this.data.orderId } },
+      {"name":"getInstallationOrderDetail","returntype":"Map","parammaps":{"orderId":this.data.orderId}},
+    ]
+    util.getDataByNames(send_data, this.handleDetail)
+  },
+
+  handleDetail(res) { 
+    var data = res.data;
+    console.log(data,'详情')
+    if (data.getInstallationOrderById.list != null) { 
+      let acceptanceImagePath = data.getInstallationOrderById.list[0].acceptanceImagePath;
+      if(acceptanceImagePath) {
+        data.getInstallationOrderById.list[0].acceptanceImagePath = acceptanceImagePath.split(',').map(path => getApp().globalData.g_url + path);
+      }
+      this.setData({
+        detailObj: data.getInstallationOrderById.list[0],
+        goodsList: data.getInstallationOrderDetail.list,
+      })
+    } else { 
+        this.setData({
+          detailObj: {},
+          goodsList:[]
+        })
+    } 
+  },
+  onBack() {
+    wx.navigateBack();
+  },
+    viewHistory() {
+    var id = this.data.orderId;
+    wx.navigateTo({
+      url:`/pages/workbench/historyFill/historyFill?id=${id}`
+    });
+  },
+
+  previewImage(e) {
+    console.log(e)
+  const urls = e.currentTarget.dataset.urls;
+  const current = e.currentTarget.dataset.current;
+  wx.previewImage({
+    urls:[current], // 需要预览的图片链接列表
+    current: current // 当前显示图片的链接
+  });
+}
+
+
+
+});

+ 6 - 0
pages/workbench/serviceOrderDetail/serviceOrderDetail.json

@@ -0,0 +1,6 @@
+{
+ "navigationBarTitleText": "工单详情",
+  "usingComponents": {
+    "l-icon": "/miniprogram_npm/lin-ui/icon/index"
+  }
+}

+ 121 - 0
pages/workbench/serviceOrderDetail/serviceOrderDetail.wxml

@@ -0,0 +1,121 @@
+<view class="container">
+
+ 
+  <view class="service-record">
+     <view class="record-header"> 
+      <text class="section-title">基本信息</text>
+       <l-button class="history-btn" bindtap="viewHistory" size="mini">服务记录</l-button>
+    </view>
+  </view>
+   <view>
+    <view class="order-info item-box"  >
+      
+      <view class="info-item">
+        <text class="label">服务单号:</text>
+        <text class="value">{{detailObj.orderNo}}</text>
+      </view>
+         <view class="info-item">
+        <text class="label">订单时间:</text>
+        <text class="value">{{detailObj.orderTime}}</text>
+      </view>
+      <!-- <view class="info-item">
+        <text class="label">服务项目:</text>
+        <text class="value">{{detailObj.projectName}}</text>
+      </view> -->
+      <view class="info-item">
+        <text class="label">客户名称:</text>
+        <text class="value">{{detailObj.customerName}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">服务人员:</text>
+        <text class="value">{{detailObj.serviceStaffNames}}</text>
+      </view>
+       <view class="info-item">
+        <text class="label">货品:</text>
+        <text class="value">{{detailObj.goodsName}}</text>
+      </view>
+     
+     
+      <view class="info-item">
+        <text class="label">总数量:</text>
+        <text class="value">{{detailObj.totalQuantity}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">剩余量:</text>
+        <text class="value">{{detailObj.uninstalledQuantity}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">已完成量:</text>
+        <text class="value">{{detailObj.installedQuantity}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">备注:</text>
+        <text class="value">{{detailObj.remark}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">预计服务完成时间:</text>
+        <text class="value">{{detailObj.estimatedCompleteTime}}</text>
+      </view>
+        <view class="info-item">
+        <text class="label">实际完成时间:</text>
+        <text class="value">{{detailObj.estimatedCompleteTime}}</text>
+      </view>
+      <view class="info-item delay-info">
+        <text class="label">距服务完成时间还剩:</text>
+        <text class="value highlight">{{detailObj.remainingTime}}天</text>
+      </view>
+      <view class="info-item delay-info">
+        <text class="label">验收图片:</text>
+        <view class="image-list">
+          <block wx:if="{{detailObj.acceptanceImagePath}}" wx:for="{{detailObj.acceptanceImagePath}}" wx:key="index">
+            <image src="{{item}}" mode="aspectFill" style="width:150rpx;height:150rpx;margin-right:10rpx;" bindtap="previewImage" data-url="{{item}}"   data-current="{{item}}"  />
+          </block>
+        </view>
+
+      </view>
+    </view>
+  </view>
+
+  <!--  -->
+  <view class="service-record">
+     <view class="record-header"> 
+      <text class="section-title">货品明细</text>
+    </view>
+  </view>
+
+   <view>
+    <view class="order-info item-box" wx:for="{{goodsList}}" wx:key="index" >
+      <view class="info-item">
+        <text class="label">服务项目:</text>
+        <text class="value">{{item.projectName}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">货品编号:</text>
+        <text class="value">{{item.goodsCode}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">货品:</text>
+        <text class="value">{{item.goodsName}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">计划总量:</text>
+        <text class="value">{{item.orderQuantity}}</text>
+      </view>
+      <view class="info-item">
+        <text class="label">已完成量:</text>
+        <text class="value">{{item.shippedQuantity}}</text>
+      </view>
+       <view class="info-item">
+        <text class="label">未完成量:</text>
+        <text class="value">{{item.unshippedQuantity}}</text>
+      </view>
+      
+      <view class="info-item">
+        <text class="label">备注:</text>
+        <text class="value">{{item.remark}}</text>
+      </view>
+    </view>
+  </view>
+  <button class="back-btn" style="flex-shrink: 0; width:140rpx;font-size: 28rpx;margin:20rpx auto; " bindtap="onBack">返回</button>
+   
+</view>

+ 114 - 0
pages/workbench/serviceOrderDetail/serviceOrderDetail.wxss

@@ -0,0 +1,114 @@
+.container {
+  padding: 20rpx;
+  min-height: 100vh;
+}
+/* 日期范围选择器 */
+.date-range-picker {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  background: #fff;
+  padding: 20rpx;
+  margin-bottom: 20rpx;
+}
+
+/* 日期项 */
+.date-item {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+/* 日期标签 */
+.date-label {
+  color: #999;
+  font-size: 28rpx;
+  margin-bottom: 10rpx;
+}
+
+/* 日期值 */
+.date-value {
+  color: #333;
+  font-size: 28rpx;
+  font-weight: 500;
+}
+
+.order-info {
+  padding: 20rpx 20rpx;
+  background: #fff;
+  margin-bottom: 10rpx;
+}
+.info-item {
+  margin-bottom: 20rpx;
+}
+.info-item > text {
+  font-size: 32rpx !important;
+}
+
+.service-record {
+  background: #fff;
+}
+.section-title {
+  color: #333 !important;
+  font-size: 32rpx;
+  font-weight: bold;
+  padding: 20rpx;
+  border-bottom: 1px solid #eee;
+}
+
+.service-order {
+  background: #fff;
+  margin-bottom: 20rpx;
+}
+
+.record-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-right: 20rpx;
+  border-bottom: 1px solid #eee;
+}
+
+.history-btn {
+  color: #3963bc;
+  font-size: 28rpx;
+}
+
+.record-content {
+  padding: 20rpx;
+  background-color: #fff;
+  margin-bottom: 20rpx;
+}
+
+.product-item {
+  margin-bottom: 10rpx;
+}
+
+.product-label {
+  display: inline-block;
+  width: 180rpx;
+  font-size: 28rpx;
+}
+
+.product-name,
+.product-value {
+  color: #333;
+}
+
+.table {
+  background-color: #f2f2f2;
+  display: flex;
+  flex-direction: column;
+  box-sizing: border-box;
+  padding: 10rpx 20rpx;
+}
+.table_box {
+  background-color: #fff;
+  display: inline-block;
+  border-radius: 10rpx;
+  width: 96%;
+  margin-bottom: 20rpx;
+  padding: 20rpx;
+  position: relative;
+}

+ 407 - 0
pages/workbench/serviceTicket/serviceTicket.js

@@ -0,0 +1,407 @@
+var util = require('../../../utils/util.js')
+const app = getApp()
+
+Page({
+  data: {
+    currentTab: '1',
+    noData: '../../../images/noData.png',
+    dataListTips: '暂无数据',
+    serviceStaffname: '',
+    showModal: false, // 控制弹窗显示
+    form: {
+      estimatedCompleteTime: '', // 存储选择的日期
+      acceptName: wx.getStorageSync('username'),
+      acceptTime: util.getRealToday(),
+    },
+    //表格请求参数~~
+    table1: {
+      name: 'getInstallationOrderList',
+      page: 1,
+      offset: 1,
+      pagecount: 9999,
+      returntype: 'Map',
+      parammaps: {
+        statusName: '待处理',
+        roleId: app.globalData.g_roleId,
+        userId: app.globalData.g_userId,
+      },
+    },
+    table2: {
+      name: 'getInstallationOrderList',
+      page: 1,
+      offset: 1,
+      pagecount: 9999,
+      returntype: 'Map',
+      parammaps: {
+        serviceStaffIds: '',
+        customerName: '',
+        statusName: '已完成',
+        roleId: app.globalData.g_roleId,
+        userId: app.globalData.g_userId,
+        completeStartTime: util.get15daysAgo(),
+        completeEndTime: util.getRealToday(),
+      },
+    },
+    itemObj: {},
+    installerList: [],
+    pendingList: [],
+    processedList: [],
+  },
+
+  onLoad: function () {
+    this.getList()
+    this.getinstallerList()
+  },
+  onShow: function () {
+    // 根据当前选中的tab刷新对应的列表
+    if (this.data.currentTab === '1') {
+      this.getList()
+    } else {
+      this.getList2()
+    }
+  },
+
+  // 服务人员
+  getinstallerList() {
+    var send_data = [
+      {
+        name: 'getUsersSelect',
+        offset: 0,
+        pagecount: 0,
+        parammaps: {
+          enable: '1',
+        },
+      },
+    ]
+
+    util.getDataByNames(send_data, this.handleInstallerList)
+  },
+  handleInstallerList(res) {
+    console.log(res, '服务人员')
+    const obj = res.data
+    if (obj.getUsersSelect) {
+      this.setData({
+        installerList: obj.getUsersSelect.list,
+      })
+    }
+  },
+  //加载表格
+  getList() {
+    this.setData({
+      ['table1.parammaps.roleId']: app.globalData.g_roleId,
+      ['table1.parammaps.userId']: app.globalData.g_userId,
+    })
+    util.getDataByName(this.data.table1, this.getListSuccess1)
+  },
+  getList2() {
+    this.setData({
+      ['table2.parammaps.roleId']: app.globalData.g_roleId,
+      ['table2.parammaps.userId']: app.globalData.g_userId,
+    })
+    util.getDataByName(this.data.table2, this.getListSuccess2)
+  },
+  getListSuccess1: function (res) {
+    const obj = res.data
+    if (obj.list != null) {
+      this.setData({
+        pendingList: res.data.list,
+        ['table1.parammaps.offset']: res.data.pageNum,
+        ['table1.total']: res.data.total,
+      })
+    } else {
+      this.setData({
+        pendingList: [],
+        ['table1.parammaps.offset']: 1,
+      })
+    }
+  },
+  getListSuccess2: function (res) {
+    const obj = res.data
+    if (obj.list != null) {
+      this.setData({
+        processedList: res.data.list,
+        ['table2.parammaps.offset']: res.data.pageNum,
+        ['table2.total']: res.data.total,
+      })
+    } else {
+      this.setData({
+        processedList: [],
+        ['table2.parammaps.offset']: 1,
+      })
+    }
+  },
+
+  //日期1
+  bindDateChange1: function (e) {
+    this.setData({
+      ['table2.parammaps.completeStartTime']: e.detail.value,
+    })
+  },
+  //日期2
+  bindDateChange2: function (e) {
+    this.setData({
+      ['table2.parammaps.completeEndTime']: e.detail.value,
+    })
+  },
+  onInstallerChange: function (e) {
+    console.log(e, 'eee')
+    this.setData({
+      serviceStaffname: this.data.installerList[e.detail.value].name,
+      ['table2.parammaps.serviceStaffIds']: this.data.installerList[e.detail.value].id,
+    })
+  },
+
+  onInputChangeClear: function (e) {
+    console.log(e, 'eee')
+    this.setData({
+      serviceStaffname: '',
+      ['table2.parammaps.serviceStaffIds']: '',
+    })
+  },
+  onInputChange: function (e) {
+    console.log(e, 'eee')
+    this.setData({
+      ['table2.parammaps.customerName']: e.detail.value,
+    })
+  },
+  changeTab(e) {
+    this.setData({
+      currentTab: e.detail.activeKey,
+      serviceStaffname: '',
+      ['table2.parammaps.serviceStaffIds']: '',
+    })
+    // 可以在这里根据tab加载不同的数据
+    if (this.data.currentTab == '1') {
+      this.getList()
+    } else {
+      this.getList2()
+    }
+  },
+
+  // 隐藏弹窗
+  hideDatePicker() {
+    this.setData({
+      showModal: false,
+    })
+    wx.showToast({
+      title: '已取消接单',
+      icon: 'none',
+      duration: 5000,
+    })
+  },
+  // 处理日期选择
+  handleDateChange(e) {
+    const estimatedCompleteTime = e.detail.value // 获取选择的日期
+    this.setData({
+      ['form.estimatedCompleteTime']: estimatedCompleteTime,
+    })
+    console.log('选择的日期:', estimatedCompleteTime)
+  },
+
+  handleAccept(e) {
+    var obj = e.target.dataset.id
+    this.setData({
+      showModal: true,
+      ['form.id']: obj.id,
+      ['form.statusName']: obj.statusName,
+    })
+  },
+  handleAcceptConfirm() {
+    if (!this.data.form.estimatedCompleteTime) {
+      wx.showToast({
+        title: '预计时间必填',
+        icon: 'none',
+        duration: 5000,
+      })
+      return
+    }
+
+    var send_data = {
+      common: { returnmap: '0' },
+      data: [
+        {
+          name: 'acceptInstallationOrder',
+          type: 'e',
+          parammaps: {
+            orderId: this.data.form.id,
+            acceptName: wx.getStorageSync('username'),
+            acceptId: wx.getStorageSync('g_userId'),
+            acceptTime: this.data.form.acceptTime,
+            estimatedCompleteTime: this.data.form.estimatedCompleteTime,
+          },
+        },
+        {
+          name: 'insertInstallationOrderProcessLog',
+          type: 'e',
+          parammaps: {
+            orderId: this.data.form.id,
+            operationType: 'accept',
+            operationUserId: wx.getStorageSync('g_userId'),
+            operationUserName: wx.getStorageSync('username'),
+            beforeStatus: this.data.form.statusName,
+            afterStatus: '处理中',
+            operationContent: '接单处理',
+          },
+        },
+      ],
+    }
+    util.execDataByConfig(send_data, this.handleAcceptList)
+  },
+  handleAcceptList(res) {
+    console.log(res, '99999')
+    if (res.code == 200) {
+      wx.showToast({
+        title: '已成功接单',
+        icon: 'success',
+        duration: 5000,
+      })
+      this.setData({
+        showModal: false,
+      })
+      this.getList()
+    }
+  },
+
+  handleReject(e) {
+    var obj = e.target.dataset.id
+    wx.showModal({
+      title: '驳回原因',
+      editable: true,
+      placeholderText: '请输入驳回原因',
+      success: (res) => {
+        if (res.confirm) {
+          const rejectReason = res.content
+          if (!rejectReason) {
+            wx.showToast({
+              title: '请输入驳回原因',
+              icon: 'none',
+              duration: 5000,
+            })
+            return
+          }
+          // 处理驳回逻辑
+          var send_data = {
+            common: { returnmap: '0' },
+            data: [
+              {
+                name: 'rejectInstallationOrder',
+                type: 'e',
+                parammaps: {
+                  orderId: obj.id,
+                  rejectReason: rejectReason,
+                  rejectId: wx.getStorageSync('g_userId'),
+                },
+              },
+
+              {
+                name: 'insertInstallationOrderProcessLog',
+                type: 'e',
+                parammaps: {
+                  orderId: obj.id,
+                  operationType: 'reject',
+                  operationUserId: wx.getStorageSync('g_userId'),
+                  operationUserName: wx.getStorageSync('username'),
+                  beforeStatus: obj.statusName,
+                  afterStatus: '接单驳回',
+                  operationContent: `驳回原因:${rejectReason}`,
+                },
+              },
+            ],
+          }
+          util.execDataByConfig(send_data, this.handleRejectList)
+        } else if (res.cancel) {
+          console.log('用户取消驳回')
+          wx.showToast({
+            title: '已取消驳回',
+            icon: 'none',
+            duration: 5000,
+          })
+        }
+      },
+    })
+  },
+  handleRejectList(res) {
+    console.log(res, '已驳回')
+    if (res.code == 200) {
+      wx.showToast({
+        title: '已驳回',
+        icon: 'success',
+        duration: 5000,
+      })
+      this.getList()
+    }
+  },
+  handleSuccess(e) {
+    var obj = e.target.dataset.id
+    wx.showModal({
+      title: '提示',
+      content: '是否确认完成?',
+      success: (res) => {
+        if (res.confirm) {
+          // 处理驳回逻辑
+          var send_data = {
+            common: { returnmap: '0' },
+            data: [
+              {
+                name: 'completeInstallationOrder',
+                type: 'e',
+                parammaps: {
+                  orderId: obj.id,
+                },
+              },
+              {
+                name: 'insertInstallationOrderProcessLog',
+                type: 'e',
+                parammaps: {
+                  orderId: obj.id,
+                  operationType: 'complete',
+                  operationUserId: wx.getStorageSync('g_userId'),
+                  operationUserName: wx.getStorageSync('username'),
+                  beforeStatus: obj.statusName,
+                  afterStatus: '已完成未验收',
+                  operationContent: '完成服务工单',
+                },
+              },
+            ],
+          }
+          util.execDataByConfig(send_data, this.handleSuccessList)
+          // 这里可以添加驳回的具体逻辑
+        } else if (res.cancel) {
+          wx.showToast({
+            title: '已取消完成',
+            icon: 'none',
+            duration: 5000,
+          })
+        }
+      },
+    })
+  },
+  handleSuccessList(res) {
+    if (res.code == 200) {
+      wx.showToast({
+        title: '已完成',
+        icon: 'success',
+        duration: 3000,
+      })
+      this.getList()
+    }
+  },
+  handleReport1(e) {
+    const id = e.currentTarget.dataset.id
+    wx.navigateTo({
+      url: `/pages/workbench/dailyFill/dailyFill?id=${id}`,
+    })
+  },
+  handleReport2(e) {
+    const id = e.currentTarget.dataset.id
+    wx.navigateTo({
+      url: `/pages/workbench/acceptFill/acceptFill?id=${id}`, // 正确跳转到验收填写页面并传入id参数
+    })
+  },
+  handleDetail(e) {
+    const id = e.currentTarget.dataset.id
+    wx.navigateTo({
+      url: `/pages/workbench/serviceOrderDetail/serviceOrderDetail?id=${id}`,
+    })
+  },
+})

+ 9 - 0
pages/workbench/serviceTicket/serviceTicket.json

@@ -0,0 +1,9 @@
+{
+  "navigationBarTitleText": "基本信息",
+  "usingComponents": {
+    "l-tabs": "/miniprogram_npm/lin-ui/tabs/index",
+    "l-tabpanel": "/miniprogram_npm/lin-ui/tabpanel/index",
+    "l-button": "/miniprogram_npm/lin-ui/button/index",
+    "l-icon": "/miniprogram_npm/lin-ui/icon/index"
+  }
+}

+ 181 - 0
pages/workbench/serviceTicket/serviceTicket.wxml

@@ -0,0 +1,181 @@
+<view class="container">
+  <!-- 顶部标签页 -->
+  <l-tabs bind:linchange="changeTab" active-color="#73a2ff">
+    <l-tabpanel tab="待处理" key="1" slot="1">
+      <view class="ticket-list">
+        <view class="ticket-item" wx:for="{{pendingList}}" >
+          <!-- 工单信息 -->
+          <view class="ticket-header">
+            <view class="ticket-no">
+              <text class="ticket-text">服务单号:{{item.orderNo}}</text>
+            </view>
+            <text class="ticket-time">{{item.orderTime}}</text>
+          </view>
+          
+          <view class="ticket-content" bindtap="handleDetail" data-id="{{item.id}}">
+            <view class="info-row">
+              <text>客户:{{item.customerName}}</text>
+              <text style="width:100rpx" class="status {{item.statusName == '未接单' ? 'status-pending' : 'status-processing'}}">{{item.statusName}}</text>
+            </view>
+            <view class="info-row">
+              <text>服务人员:{{item.serviceStaffNames}}</text>
+            </view>
+            <view class="info-row">
+              <text>预计服务完成时间:{{item.estimatedCompleteTime || '--'}}</text>
+            </view>
+            <view class="info-row">
+              <text>货品:{{item.goodsName}}</text>
+            </view>
+          </view>
+
+          <!-- 底部按钮 -->
+           <!--  -->
+          <view class="ticket-actions" wx:if="{{item.statusName == '未接单'}}" >
+            <l-button size="mini" type="default"   plain="{{true}}" bindtap="handleAccept" data-id="{{item}}">接单</l-button>
+            <l-button size="mini" type="error" plain="{{true}}" bindtap="handleReject" data-id="{{item}}">驳回</l-button>
+          </view>
+          <view class="ticket-actions" wx:if="{{item.statusName == '处理中' || item.statusName == '已接单'}}">
+            <l-button size="mini" type="default" plain="{{true}}" bindtap="handleReport1" data-id="{{item.id}}">每日填报</l-button>
+            <l-button size="mini" type="error" plain="{{true}}" bindtap="handleSuccess" data-id="{{item}}">完成</l-button>
+          </view>
+          <!-- wx:if="{{item.statusName == '已完成未验收'}}" -->
+          <view class="ticket-actions"  wx:if="{{item.statusName == '已完成未验收'}}">
+            <l-button size="mini" type="default" plain="{{true}}" bindtap="handleReport2" data-id="{{item.id}}" data-type="2">验收</l-button>
+          </view>
+        </view>
+      </view>
+     <block wx:if="{{!pendingList || pendingList.length === 0}}">
+      <view class="table">
+         <image style="width: 400rpx; height: 400rpx;margin:0 auto" mode="aspectFit" src="{{noData}}"></image>
+         <text style="margin:0 auto">{{dataListTips}}</text> 
+      </view>
+    </block>
+    </l-tabpanel>
+
+    <l-tabpanel tab="已完成" key="2" slot="2">
+      <view class="process-box">
+      <view class="search-container" >
+        <view class="date-range-picker">
+          <!-- 开始日期 -->
+          <picker 
+            mode="date" 
+            start="2015-09-01"
+            name="completeStartTime"
+            bindchange="bindDateChange1"
+            place
+          >
+            <view class="date-item">
+              <!-- <text class="date-label">开始日期</text> -->
+              <text class="date-value">{{table2.parammaps.completeStartTime}}</text>
+            </view>
+          </picker>
+          <!-- 分隔符 -->
+          <text class="separator">~</text>
+          <!-- 结束日期 -->
+          <picker 
+            mode="date" 
+            start="2015-09-01"
+            name="endDate"
+            bindchange="bindDateChange2"
+          >
+            <view class="date-item">
+              <text class="date-value">{{table2.parammaps.completeEndTime}}</text>
+            </view>
+          </picker>
+        </view>
+       <!-- 搜索栏 -->
+        <view class="search-bar" style="display: flex; align-items: center;">
+          <picker 
+            mode="selector"
+            range="{{installerList}}" 
+            range-key="name"
+            value="{{statusIndex}}"
+            bindchange="onInstallerChange"
+            bindcancel="onInputChangeClear"
+            style="flex: 1; margin-right: 10px;"
+            class="search-input"
+          >
+            <view class="picker-view">
+              <text style="color: {{serviceStaffname ? '#333333' : '#999999'}}">{{ serviceStaffname || '请选择服务人员'}}</text>
+            </view>
+          </picker>
+          <input 
+            class="search-input" 
+            placeholder="客户名称" 
+            placeholder-class="placeholder"
+            style="flex: 1; margin-right: 10px;"
+            value="{{table2.parammaps.customerName}}"
+            bindchange="onInputChange"
+          />
+          <button class="search-btn" bindtap="getList2"   style="flex-shrink: 0;width:110rpx; font-size: 12px;margin:0; background-color: #3963bc; color: white; border: none;" >搜索</button>
+             
+
+        </view>
+      </view>
+       <view  class="processed-list">
+        <view class="processed-item" wx:for="{{processedList}}">
+          <view class="ticket-header">
+            <view class="ticket-no">
+            <text class="ticket-text">安装单号:{{item.orderNo}}</text>
+            </view>
+            <text  class="ticket-time">{{item.completionTime}}</text>
+          </view>
+          <view class="processed-content" bindtap="handleDetail" data-id="{{item.id}}">
+             <view class="info-row">
+              <text>客户:{{item.customerName}}</text>
+              <text class="status status-processing" style="width:100rpx">{{item.statusName}}</text>
+            </view>
+            <text>安装人:{{item.serviceStaffNames}}</text>
+            <text>预计完成时间:{{item.actualCompleteTime}}</text>
+            <text>安装产品:{{item.goodsName}}</text>
+            <text>备注: {{item.remark}}</text>
+          </view>
+        </view>
+       </view>
+       <block wx:if="{{!processedList || processedList.length === 0}}">
+        <view class="table">
+          <image style="width: 400rpx; height: 400rpx;margin:0 auto" mode="aspectFit" src="{{noData}}"></image>
+          <text style="margin:0 auto">{{dataListTips}}</text> 
+        </view>
+    </block>
+      </view>
+    </l-tabpanel>
+
+   
+
+  </l-tabs>
+
+<!-- 弹窗 -->
+  <view class="modal" wx:if="{{showModal}}" >
+    <view class="title" >
+                确认接单
+    </view>
+    <view class="modal-content">
+        <view class="product-item">
+          <text class="product-label">接单人:</text>
+          <input class="quantity-input" type="number" value="{{form.acceptName}}" disabled="{{true}}"  />
+        </view>
+        <view class="product-item">
+          <text class="product-label">接单时间:</text>
+           <input class="quantity-input" type="number" value="{{form.acceptTime}}" disabled="{{true}}"  />
+        </view>
+       <view class="product-item">
+          <text class="product-label">预计完成时间:</text>
+          <picker class="quantity-input"  mode="date" bindchange="handleDateChange">
+            <view class="date-input">
+              <text>{{form.estimatedCompleteTime || '请选择日期'}}</text>
+            </view>
+          </picker>
+        </view>
+      <!-- 弹窗标题 -->
+       <view style="text-align:right;margin-top:20rpx">
+            <l-button size="mini" type="primary" plain="{{true}}" style="margin-right:20rpx;"  bindtap="hideDatePicker" > 取消</l-button>
+            <l-button size="mini"  bindtap="handleAcceptConfirm">确认接单</l-button>
+       </view>
+      
+    </view>
+  </view>
+
+  <!-- 遮罩层 -->
+  <view class="mask" wx:if="{{showModal}}" bindtap="hideDatePicker"></view>
+</view>

+ 269 - 0
pages/workbench/serviceTicket/serviceTicket.wxss

@@ -0,0 +1,269 @@
+.container {
+  padding: 0;
+  background: #f2f2f2;
+  min-height: 100vh;
+}
+
+.ticket-list {
+  padding: 20rpx;
+}
+
+.ticket-item {
+  background: #fff;
+  border-radius: 8rpx;
+  padding: 20rpx;
+  margin-bottom: 20rpx;
+}
+
+.ticket-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-bottom: 15rpx;
+}
+
+.ticket-no {
+  display: flex;
+  align-items: center;
+  font-size: 28rpx;
+}
+.ticket-text {
+  color: #333 !important;
+  font-size: 32rpx;
+  font-weight: bold;
+}
+
+.ticket-time {
+  color: #666;
+  font-size: 28rpx;
+}
+
+.ticket-content {
+  padding: 15rpx 0;
+}
+
+.info-row {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 10rpx;
+  font-size: 28rpx;
+}
+
+.status {
+  font-size: 24rpx;
+  padding: 4rpx 12rpx;
+  border-radius: 4rpx;
+}
+
+.ticket-actions {
+  display: flex;
+  justify-content: flex-end;
+  gap: 20rpx;
+  padding-top: 15rpx;
+  border-top: 1rpx solid #eee;
+}
+
+/* Lin UI按钮样式覆盖 */
+.l-btn {
+  min-width: 160rpx !important;
+}
+
+.processed-list {
+  margin-top: 10rpx;
+}
+
+.processed-item {
+  background-color: #fff;
+  border-radius: 5rpx;
+  padding: 20rpx;
+  margin-bottom: 15rpx; /* 增加底部间距 */
+  box-shadow: 0 2rpx 5rpx rgba(0, 0, 0, 0.1);
+}
+
+.processed-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 10rpx;
+}
+
+.order-number {
+  font-weight: bold;
+  font-size: 16rpx; /* 增加字体大小 */
+  color: #333;
+}
+
+.completion-time {
+  font-size: 14rpx; /* 增加字体大小 */
+  color: #999;
+}
+
+.processed-content {
+  font-size: 14rpx;
+  color: #666;
+  margin-top: 5rpx; /* 增加顶部间距 */
+}
+
+.processed-content text {
+  display: block; /* 每个文本占一行 */
+  margin-bottom: 5rpx; /* 增加文本间距 */
+}
+
+.status {
+  font-weight: bold;
+  color: #4caf50; /* 状态颜色 */
+}
+
+.completed {
+  color: #4caf50; /* 已完成状态颜色 */
+}
+
+/* 日期范围选择器 */
+.date-range-picker {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: #fff;
+  padding: 20rpx;
+}
+
+/* 日期项 */
+.date-item {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+/* 日期标签 */
+.date-label {
+  color: #999;
+  font-size: 24rpx;
+  margin-bottom: 10rpx;
+}
+
+/* 日期值 */
+.date-value {
+  color: #333;
+  font-size: 28rpx;
+  font-weight: 500;
+}
+
+/* 分隔符 */
+.separator {
+  margin: 0 20rpx;
+  color: #666;
+  font-size: 28rpx;
+}
+
+.process-box {
+  padding: 20rpx;
+}
+
+.table {
+  background-color: #f2f2f2;
+  display: flex;
+  flex-direction: column;
+  box-sizing: border-box;
+  padding: 10rpx 20rpx;
+}
+.table_box {
+  background-color: #fff;
+  display: inline-block;
+  border-radius: 10rpx;
+  width: 96%;
+  margin-bottom: 20rpx;
+  padding: 20rpx;
+  position: relative;
+}
+
+.status-pending {
+  color: #ff4d4f;
+}
+
+.status-processing {
+  color: #52c41a;
+}
+.search-input {
+  height: 60rpx;
+  line-height: 60rpx;
+  text-align: centerå;
+}
+
+/* 弹窗样式 */
+.modal {
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  width: 90%;
+  background-color: #fff;
+  border-radius: 10px;
+  z-index: 1000;
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+}
+
+/* 弹窗内容 */
+.modal-content {
+  padding: 50rpx 20rpx;
+}
+
+/* 弹窗标题 */
+.modal-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  font-size: 18rpx;
+  font-weight: bold;
+  margin-bottom: 20px;
+}
+
+/* 关闭按钮 */
+.close-btn {
+  background: none;
+  border: none;
+  font-size: 24px;
+  color: #999;
+  padding: 0;
+}
+
+/* 遮罩层 */
+.mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.5);
+  z-index: 999;
+}
+.product-item > text {
+  font-size: 32rpx;
+}
+.quantity-input {
+  display: inline-block;
+  width: 52%;
+  border: 1px solid #ddd;
+  padding: 16rpx 16rpx;
+  border-radius: 4px;
+  font-size: 28rpx;
+  color: #999;
+  margin-bottom: 10rpx;
+}
+.product-label {
+  display: inline-block;
+  width: 220rpx;
+  font-size: 32rpx;
+  /* position: relative;
+  top: -20rpx; */
+  text-align: right;
+  padding-right: 10rpx;
+  color: #666;
+}
+.title {
+  font-size: 34rpx;
+  text-align: center;
+  padding: 40rpx 20rpx 0 20rpx;
+  color: #666;
+}

+ 0 - 2
pages/workbench/siteService/siteService.js

@@ -9,8 +9,6 @@ Page({
     noData:'../../../images/noData.png',
     dataListTips: "暂无数据",
     g_createrId:"",
-  
-   
     inputvalue:"",
 
     statusNameList: [

+ 5 - 1
pages/workbench/workbench.js

@@ -6,7 +6,8 @@ Page({
       { img: "/images/workbench/pp-img1.png", title: "电话回访" },
       { img: "/images/workbench/pp-img2.png", title: "远程服务"},
       { img: "/images/workbench/pp-img3.png", title: "现场服务"},
-      { img: "/images/workbench/pp-img4.png", title: "投诉处理"}
+      { img: "/images/workbench/pp-img4.png", title: "投诉处理" },
+      { img: "/images/workbench/fuwudan.png", title: "服务工单"}
     ]
   },
   onLoad: function (options) {
@@ -31,6 +32,9 @@ Page({
         break;
         case "现场服务":
           wx.navigateTo({ url:"./siteService/siteService"})
+        break;
+        case "服务工单":
+          wx.navigateTo({ url:"./serviceTicket/serviceTicket"})
           break;
     }
 

+ 2 - 1
project.private.config.json

@@ -3,5 +3,6 @@
     "setting": {
         "compileHotReLoad": true
     },
-    "projectname": "CRM"
+    "projectname": "CRM",
+    "libVersion": "3.6.6"
 }

+ 103 - 68
utils/util.js

@@ -1,7 +1,7 @@
-const app = getApp();
+const app = getApp()
 function is_loading() {
   wx.showLoading({
-    title: '加载中'
+    title: '加载中',
   })
 }
 
@@ -9,29 +9,28 @@ function over_loading() {
   wx.hideLoading()
 }
 
-
 function tips_fail() {
   wx.showToast({
     title: '网络错误',
     icon: 'none',
-    duration: 2000
+    duration: 2000,
   })
 }
 function postDataByName(data, success_fn) {
-  wx.setStorageSync('isLoading', 'true'); 
+  wx.setStorageSync('isLoading', 'true')
   wx.request({
     url: app.globalData.g_url + 'authdata/PostDataByName',
     data: data,
     method: 'POST',
     header: {
-      "Content-Type": "json",
-      "token": app.globalData.g_token
+      'Content-Type': 'json',
+      token: app.globalData.g_token,
     },
     success: function (res) {
       //console.log("res",res)
       over_loading()
-      wx.setStorageSync('isLoading', 'false'); 
-      if (res.data.code ==  200  ) {
+      wx.setStorageSync('isLoading', 'false')
+      if (res.data.code == 200) {
         success_fn(res.data)
       }
     },
@@ -39,104 +38,128 @@ function postDataByName(data, success_fn) {
       console.log(error)
       tips_fail()
       over_loading()
-      wx.setStorageSync('isLoading', 'false');
-    }
+      wx.setStorageSync('isLoading', 'false')
+    },
   })
 }
- 
+
 function execDataByConfig(data, success_fn) {
-  wx.setStorageSync('isLoading', 'true'); 
+  wx.setStorageSync('isLoading', 'true')
   is_loading()
   wx.request({
     url: app.globalData.g_url + 'authdata/ExecDataByConfig',
     data: data,
     method: 'POST',
     header: {
-      "Content-Type": "json",
-      "token": app.globalData.g_token
+      'Content-Type': 'json',
+      token: app.globalData.g_token,
     },
     success: function (res) {
       //console.log("res",res)
-      if (res.data.code ==  200  ) {
+      if (res.data.code == 200) {
         success_fn(res.data)
       }
       over_loading()
-      wx.setStorageSync('isLoading', 'false'); 
+      wx.setStorageSync('isLoading', 'false')
     },
     fail: function (error) {
       console.log(error)
       tips_fail()
       over_loading()
-      wx.setStorageSync('isLoading', 'false'); 
-    }
+      wx.setStorageSync('isLoading', 'false')
+    },
   })
 }
 
 function getDataByName(data, success_fn) {
-  wx.setStorageSync('isLoading', 'true'); 
+  wx.setStorageSync('isLoading', 'true')
   is_loading()
   wx.request({
     url: app.globalData.g_url + 'authdata/GetDataByName',
     data: data,
     method: 'POST',
     header: {
-      "Content-Type": "json",
-      "token": app.globalData.g_token
+      'Content-Type': 'json',
+      token: app.globalData.g_token,
     },
     success: function (res) {
       //console.log("res",res)
-      if (res.data.code ==  200  ) {
+      if (res.data.code == 200) {
         success_fn(res.data)
       }
       over_loading()
-      wx.setStorageSync('isLoading', 'false'); 
+      wx.setStorageSync('isLoading', 'false')
     },
     fail: function (error) {
       console.log(error)
       tips_fail()
       over_loading()
-      wx.setStorageSync('isLoading', 'false'); 
-    }
+      wx.setStorageSync('isLoading', 'false')
+    },
+  })
+}
+
+function getDataByNames(data, success_fn) {
+  wx.setStorageSync('isLoading', 'true')
+  is_loading()
+  wx.request({
+    url: app.globalData.g_url + 'authdata/GetDataByNames',
+    data: data,
+    method: 'POST',
+    header: {
+      'Content-Type': 'json',
+      token: app.globalData.g_token,
+    },
+    success: function (res) {
+      //console.log("res",res)
+      if (res.data.code == 200) {
+        success_fn(res.data)
+      }
+      over_loading()
+      wx.setStorageSync('isLoading', 'false')
+    },
+    fail: function (error) {
+      console.log(error)
+      tips_fail()
+      over_loading()
+      wx.setStorageSync('isLoading', 'false')
+    },
   })
 }
 
 function ajax(url, data, method, success_fn, error_fn) {
-  wx.setStorageSync('isLoading', 'true'); 
+  wx.setStorageSync('isLoading', 'true')
   is_loading()
   wx.request({
     url: url,
     data: data,
     method: method,
     header: {
-      "Content-Type": "json"
+      'Content-Type': 'json',
     },
     success: function (res) {
       //console.log("res",res)
-     
-      if (res.data.code ==  200  ) {
+
+      if (res.data.code == 200) {
         success_fn(res.data)
-        
       } else {
         if (error_fn) {
           error_fn(res)
         }
-        
       }
 
-   
       over_loading()
-      wx.setStorageSync('isLoading', 'false');
+      wx.setStorageSync('isLoading', 'false')
     },
     fail: function (error) {
       console.log(error)
       tips_fail()
       over_loading()
-      wx.setStorageSync('isLoading', 'false');
-    }
+      wx.setStorageSync('isLoading', 'false')
+    },
   })
 }
 
-
 // function ajax(url, data, method, success_fn, error_fn) {
 //   is_loading()
 //   wx.request({
@@ -147,7 +170,7 @@ function ajax(url, data, method, success_fn, error_fn) {
 //       "Content-Type": "json"
 //     },
 //     success: function (res) {
-     
+
 //       if (res.data.code == 1 || res.data.code == 0) {
 //         success_fn(res)
 //         over_loading()
@@ -167,63 +190,74 @@ function ajax(url, data, method, success_fn, error_fn) {
 // }
 
 function getYesterday() {
-  var day1 = new Date();
-  day1.setTime(day1.getTime() - 24 * 60 * 60 * 1000);
-  var s1 = day1.getFullYear() + "-" + (day1.getMonth() + 1) + "-" + day1.getDate();
+  var day1 = new Date()
+  day1.setTime(day1.getTime() - 24 * 60 * 60 * 1000)
+  var s1 = day1.getFullYear() + '-' + (day1.getMonth() + 1) + '-' + day1.getDate()
   return s1
 }
 
-
-
 function getRealToday() {
-  var day = new Date();
-  day.setTime(day.getTime());
-  var s = day.getFullYear() + "-" + (day.getMonth() + 1) + "-" + day.getDate();
+  var day = new Date()
+  day.setTime(day.getTime())
+  var s =
+    day.getFullYear() +
+    '-' +
+    (day.getMonth() + 1).toString().padStart(2, '0') +
+    '-' +
+    day.getDate().toString().padStart(2, '0')
+
   return s
 }
 
-
 function getReal7daysToday() {
-  var day11 = new Date();
-  day11.setTime(day11.getTime() - 24 * 6 * 60 * 60 * 1000);
-  var s11 = day11.getFullYear() + "-" + (day11.getMonth() + 1) + "-" + day11.getDate();
+  var day11 = new Date()
+  day11.setTime(day11.getTime() - 24 * 6 * 60 * 60 * 1000)
+  var s11 = day11.getFullYear() + '-' + (day11.getMonth() + 1) + '-' + day11.getDate()
   return s11
 }
 
 function getToday() {
-  var day2 = new Date();
-  day2.setTime(day2.getTime());
-  var s2 = day2.getFullYear() + "-" + (day2.getMonth() + 1) + "-" + day2.getDate();
+  var day2 = new Date()
+  day2.setTime(day2.getTime())
+  var s2 =
+    day2.getFullYear() +
+    '-' +
+    String(day2.getMonth() + 1).padStart(2, '0') +
+    '-' +
+    String(day2.getDate() + 1).padStart(2, '0')
   return s2
 }
 
 function get7daysAgo() {
-  var day4 = new Date();
-  day4.setTime(day4.getTime() - 24 * 6 * 60 * 60 * 1000);
-  var s4 = day4.getFullYear() + "-" + (day4.getMonth() + 1) + "-" + day4.getDate();
+  var day4 = new Date()
+  day4.setTime(day4.getTime() - 24 * 6 * 60 * 60 * 1000)
+  var s4 =
+    day4.getFullYear() +
+    '-' +
+    String(day4.getMonth() + 1).padStart(2, '0') +
+    '-' +
+    String(day4.getDate()).padStart(2, '0')
   return s4
 }
 
 function get15daysAgo() {
-  var day5 = new Date();
-  day5.setTime(day5.getTime() - 24 * 15 * 60 * 60 * 1000);
-  var s5 = day5.getFullYear() + "-" + (day5.getMonth() + 1) + "-" + day5.getDate();
+  var day5 = new Date()
+  day5.setTime(day5.getTime() - 24 * 15 * 60 * 60 * 1000)
+  var s5 = day5.getFullYear() + '-' + (day5.getMonth() + 1) + '-' + day5.getDate()
   return s5
 }
 
 function get91daysAgo() {
-  var day6 = new Date();
-  day6.setTime(day6.getTime() - 24 * 90 * 60 * 60 * 1000);
-  var s6 = day6.getFullYear() + "-" + (day6.getMonth() + 1) + "-" + day6.getDate();
+  var day6 = new Date()
+  day6.setTime(day6.getTime() - 24 * 90 * 60 * 60 * 1000)
+  var s6 = day6.getFullYear() + '-' + (day6.getMonth() + 1) + '-' + day6.getDate()
   return s6
 }
 
-
-
 function getTomorrow() {
-  var day3 = new Date();
-  day3.setTime(day3.getTime() + 24 * 60 * 60 * 1000);
-  var s3 = day3.getFullYear() + "-" + (day3.getMonth() + 1) + "-" + day3.getDate();
+  var day3 = new Date()
+  day3.setTime(day3.getTime() + 24 * 60 * 60 * 1000)
+  var s3 = day3.getFullYear() + '-' + (day3.getMonth() + 1) + '-' + day3.getDate()
   return s3
 }
 
@@ -239,5 +273,6 @@ module.exports = {
   get7daysAgo: get7daysAgo,
   get91daysAgo: get91daysAgo,
   get15daysAgo: get15daysAgo,
-  getTomorrow: getTomorrow
+  getTomorrow: getTomorrow,
+  getDataByNames: getDataByNames,
 }

Some files were not shown because too many files changed in this diff