MrShi
2024-12-20 be290203369f9cbd618948901f79db5964bf01a6
Merge branch 'master' of http://139.186.142.91:10010/r/productDev/funingyunwei
已修改54个文件
1344 ■■■■ 文件已修改
admin/.env 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/business/OperaAreasWindow.vue 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/Inspection/components/OperaYwPatrolLineWindow.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/workorder/components/OperaYwWorkorderWindow.vue 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/api/staff.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/api/yw.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/manifest.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/login.vue 497 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/operation/detail.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/operation/device.vue 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/operation/record.vue 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/polling/detail.vue 188 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/polling/task.vue 100 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/workOrder/detail.vue 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/workOrder/edit.vue 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/workOrder/list.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/utils/config.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_gateway/src/main/java/com/doumee/api/gateway/JwtAuthController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_gateway/src/main/resources/application-pro.yml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_gateway/src/main/resources/bootstrap.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/cloud/SystemUserCloudController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/config/jwt/JwtTokenUtil.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/dao/system/dto/LoginDTO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/dao/system/dto/LoginPhoneDTO.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/dao/system/model/SystemUser.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/service/system/SystemLoginService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/service/system/SystemUserService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_service/src/main/java/com/doumee/service/system/impl/SystemUserServiceImpl.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_timer/src/main/resources/application-pro.yml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/system_timer/src/main/resources/bootstrap.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/admin_timer/src/main/java/com/doumee/api/WxTokenTimerController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/admin_timer/src/main/java/com/doumee/api/YwTimerController.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/SmsEmailColudController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/YwContractCloudController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/YwPatrolSchemeCloudController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/YwPatrolTaskRecordController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/web/VisitorWebController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_admin/src/main/resources/bootstrap.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/YwPatrolTaskRecord.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/MemberService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/YwPatrolTaskRecordService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/SmsEmailServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwContractBillServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwContractServiceImpl.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwDeviceRecordServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwPatrolSchemeServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwPatrolTaskRecordServiceImpl.java 75 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwPatrolTaskServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/hksync/HkSyncVisitServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/visits/dmvisit_service/src/main/resources/application-pro.yml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/.env
@@ -3,8 +3,8 @@
# 路由方式
VUE_APP_ROUTER_MODE = 'hash'
# 项目上下文路径 fn_admin/#/
VUE_APP_CONTEXT_PATH = '/'
# 项目上下文路径
VUE_APP_CONTEXT_PATH = '/fn_admin'
# 接口前缀
VUE_APP_API_PREFIX = '/gateway_interface'
admin/src/components/business/OperaAreasWindow.vue
@@ -6,8 +6,8 @@
    @confirm="confirm"
  >
    <el-form :model="form" ref="form" label-width="100px" label-suffix=":" :rules="rules">
      <el-form-item :label="form.type==0?'市名称':'县区名称'" prop="name">
        <el-input v-model="form.name" :placeholder="form.type==0?'输入市名称':'输入县区名称'" v-trim/>
      <el-form-item :label="form.type==1?'市名称':'县区名称'" prop="name">
        <el-input v-model="form.name" :placeholder="form.type==1?'输入市名称':'输入县区名称'" v-trim/>
      </el-form-item>
      <el-form-item label="排序码" prop="sortnum">
        <el-input v-model="form.sortnum" placeholder="请输入排序码" v-trim/>
@@ -31,7 +31,7 @@
        parentId: null,
        name: null,
        sortnum: '0',
        type: '',
        type: null
      },
      // 验证规则
      rules: {
@@ -45,6 +45,31 @@
    })
  },
  methods: {
    open (title, target) {
      this.title = title
      this.visible = true
      this.$nextTick(() => {
        this.$refs.form.resetFields()
        this.form[this.configData['field.id']] = null
      })
      // 新建
      if (target == null) {
        this.$nextTick(() => {
          for (const key in this.form) {
            this.form[key] = target[key]
          }
        })
        return
      }
      // 编辑
      this.$nextTick(() => {
        for (const key in this.form) {
          this.form[key] = target[key]
        }
      })
      console.log(this.form)
    },
    // 确认新建
    __confirmCreate () {
      this.$refs.form.validate((valid) => {
admin/src/views/Inspection/components/OperaYwPatrolLineWindow.vue
@@ -32,7 +32,7 @@
    </el-form>
    <!--  -->
    <el-dialog title="添加巡检点" :close-on-click-modal="false" append-to-body :visible.sync="isShowModal" width="780px">
    <el-dialog title="添加巡检点" :close-on-click-modal="false" append-to-body :visible.sync="isShowModal" width="880px">
      <!-- <el-select class="w400" v-model="selPoint" clearable multiple filterable>
        <el-option v-for="item in pointList" :value="item.id" :label="item.name"></el-option>
      </el-select> -->
@@ -50,6 +50,8 @@
        </el-form-item>
        <el-button type="primary" @click="initData">搜索</el-button>
        <el-button @click="reset">重置</el-button>
        <el-button type="primary" @click="editClick()" icon="el-icon-plus"
                   v-permissions="['business:ywpatrolpoint:create']">新建巡检点</el-button>
      </el-form>
      <el-table @selection-change="handleSelectionChange" v-loading="isWorking.search" :data="pointList" stripe>
@@ -67,12 +69,14 @@
        <el-button type="primary" @click="subModal">确 定</el-button>
      </span>
    </el-dialog>
    <OperaYwPatrolPointWindow ref="operaYwPatrolPointWindow" @success="handlePageChange" />
  </GlobalWindow>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import OperaYwPatrolPointWindow from '@/views/Inspection/components/OperaYwPatrolPointWindow'
import Pagination from '@/components/common/Pagination'
import { fetchList as getFetchList } from '@/api/Inspection/ywPatrolPoint'
import { create, updateById, detailById } from '@/api/Inspection/ywPatrolLine'
@@ -81,7 +85,7 @@
export default {
  name: 'OperaYwPatrolLineWindow',
  extends: BaseOpera,
  components: { GlobalWindow, Pagination },
  components: { GlobalWindow, Pagination,OperaYwPatrolPointWindow },
  data() {
    return {
      // 表单数据
@@ -120,6 +124,10 @@
    })
  },
  methods: {
    editClick(row) {
        this.$refs.operaYwPatrolPointWindow.open('新建巡检点')
      // this.$refs.operaYwPatrolPointWindow.initData()
    },
    confirm() {
      const { form, list } = this
      this.$refs['form'].validate((valid) => {
admin/src/views/workorder/components/OperaYwWorkorderWindow.vue
@@ -142,35 +142,35 @@
      this.getCate()
      // 新建
      if (target == null) {
        this.form = {
          id: null,
          editDate: '',
          floor: '',
          title: '',
          remark: '',
          status: '',
          sortnum: '',
          content: '',
          getDate: '',
          projectId: '',
          buildingId: '',
          floorId: '',
          roomId: '',
          userId: '',
          submitDate: '',
          cateId: '',
          areaType: '0',
          code: '',
          dealStatus: '',
          dispatchUserId: '',
          dispatchDate: '',
          dispatchInfo: '',
          dealUserId: '',
          dealDate: '',
          dealInfo: '',
          dealType: ''
        }
        this.$nextTick(() => {
          this.$refs.form = {
            id: null,
            editDate: '',
            floor: '',
            title: '',
            remark: '',
            status: '',
            sortnum: '',
            content: '',
            getDate: '',
            projectId: '',
            buildingId: '',
            floorId: '',
            roomId: '',
            userId: '',
            submitDate: '',
            cateId: '',
            areaType: '0',
            code: '',
            dealStatus: '',
            dispatchUserId: '',
            dispatchDate: '',
            dispatchInfo: '',
            dealUserId: '',
            dealDate: '',
            dealInfo: '',
            dealType: ''
          }
          this.buildList = []
          this.roomList = []
          this.levelList = []
h5/api/staff.js
@@ -15,6 +15,14 @@
    data
  })
}
// 授权
export const ywWxAuthorize = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/web/visitor/ywWxAuthorize',
    method: 'get',
    data
  })
}
export const findInternalList = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/system/user/findInternalList',
@@ -31,7 +39,7 @@
// loginout
export const logoutPost = (data) => {
  return http({
    url: '/logout',
    url: 'logout',
    method: 'post',
    data
  })
h5/api/yw.js
@@ -127,4 +127,11 @@
    url: 'visitsAdmin/cloudService/business/category/page',
    data
  })
}
//
export const getPointRecordByCode = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/ywPatrolTaskRecord/getPointRecordByCode',
    data
  })
}
h5/manifest.json
@@ -129,9 +129,9 @@
                "/gateway_interface" : {
                    // 这个字段名需与你配置的basePrefixUrl一致,系统识别到带有/dev-api请求的地址时,会在前面拼接上代理服务器地址
                    // "target" : "http://172.20.10.7:10010", // 代理服务器域名或IP地址
                    "target" : "http://192.168.0.163:10010", // 代理服务器域名或IP地址
                    // "target" : "http://192.168.0.163:10010", // 代理服务器域名或IP地址
                    // "target" : "http://10.50.250.253:8088/gateway_interface", // 代理服务器域名或IP地址
                    // "target" : "http://192.168.0.173/gateway_interface", // 代理服务器域名或IP地址
                    "target" : "https://zhcg.fnwtzx.com/gateway_interface", // 代理服务器域名或IP地址
                    "changeOrigin" : true, // 允许跨域 
                    "pathRewrite" : {
                        "^/gateway_interface" : ""
h5/pages.json
@@ -87,7 +87,7 @@
    ],
    "globalStyle": {
        "navigationBarTextStyle": "black",
        "navigationBarTitleText": "",
        "navigationStyle": "custom",
        "navigationBarBackgroundColor": "#ffffff",
        "backgroundColor": "#ffffff"
    },
h5/pages/index.vue
@@ -74,12 +74,13 @@
                    url: item.url
                })
            },
            loginOut() {
                this.$store.commit('empty')
            loginOut() {
                logoutPost()
                this.$store.commit('empty')
                uni.redirectTo({
                    url: '/pages/login'
                })
                })
                // window.location.href= 'https://zhcg.fnwtzx.com/fn_h5'
            },
        }
h5/pages/login.vue
@@ -1,213 +1,284 @@
<template>
  <view class="login">
    <view class="login_title">欢迎登录</view>
    <view class="login_title login_title2">阜宁文体中心</view>
    <view class="login_list">
      <view class="login_list_item">
        <image src="@/static/login_ic_phone@2x.png" mode="widthFix" />
        <input v-model="form.phone" maxlength="18" placeholder="请输入手机号" />
      </view>
<!--     <view class="login_list_item">
        <image src="@/static/login_ic_password@2x.png" mode="widthFix" />
        <input v-model="form.password" type="password" placeholder="密码" />
      </view> -->
     <view class="login_list_item">
        <image src="@/static/login_ic_password@2x.png" mode="widthFix"></image>
        <input v-model="form.code" placeholder="请输入验证码" type="text" />
        <view v-if="downTime == 0" class="btn" @click="sendSms">获取验证码</view>
        <view v-else class="btn gray">{{ downTime }}</view>
      </view>
    </view>
    <view class="login_btn">
      <view class="login_btn_n" @click="onLogin">登录</view>
    </view>
  </view>
</template>
<script>
import { loginPost, getUserInfo, sendSMsPost } from '@/api'
import { mapState, mapMutations } from 'vuex'
export default {
  name: 'login',
  data() {
    return {
      form: {
                phone: '18888888888',
                code: '1'
      },
            downTime: 0
    }
  },
  onLoad() {
  },
  onBackPress(options) {
    uni.redirectTo({
      url: '/pages/login/login'
    })
    return true
  },
  methods: {
    ...mapMutations(["setToken", "setUserInfo"]),
        sendSms() {
            this.downTime = 60
            let timer = setInterval(() => {
                if(this.downTime == 0) return clearInterval(timer)
                this.downTime = this.downTime - 1
            }, 1000)
            const { form } = this
            sendSMsPost({
                phone: form.phone,
                type: 0
            }).then(res => {
                this.showToast('短信发送成功')
            })
        },
    onLogin() {
      const { form, ProtocolFlag } = this
      // if (!ProtocolFlag) return uni.showToast({
      //   title: '请先阅读并同意用户协议',
      //   icon: 'none'
      // })
      if (!form.phone) return uni.showToast({
        title: '手机号不能为空',
        icon: 'none'
      })
      if (!form.code) return uni.showToast({
        title: '验证码不能为空',
        icon: 'none'
      })
      loginPost({
        ...form,
        openId: this.$store.state.openId
      }).then(res => {
        if (res.code === 200) {
          this.setToken(res.data)
                    this.showToast('登录成功')
          getUserInfo().then(ress => {
            this.setUserInfo(ress.data)
            uni.redirectTo({
              url: "/pages/index"
            })
          })
        }
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.login {
  width: 100%;
  height: 100vh;
  display: flex;
  padding-top: 130rpx;
  box-sizing: border-box;
  align-items: center;
  flex-direction: column;
  background: linear-gradient( 180deg, #C5DDFF 0%, #FFFFFF 100%);
  .login_title {
    font-weight: 500;
    font-size: 52rpx;
    color: #222222;
    margin-top: 180rpx;
        width: 100%;
        padding-left: 60rpx;
  }
    .login_title2{
        margin-top: 10rpx;
        margin-bottom: 80rpx;
    }
  .login_list {
    width: 100%;
    padding: 0 60rpx;
    box-sizing: border-box;
    .login_list_item {
      width: 100%;
      border-radius: 50rpx;
      height: 98rpx;
      padding: 0 40rpx;
      box-sizing: border-box;
      background: #ffffff;
      margin-bottom: 40rpx;
      display: flex;
      align-items: center;
      justify-content: space-between;
      &:last-child {
        margin-bottom: 0 !important;
      }
      image {
        flex-shrink: 0;
        width: 40rpx;
        height: 40rpx;
      }
      .btn{
          width: 145rpx;
          color:  $primaryColor;
                text-align: center;
      }
            .gray{
                color: #999999;
            }
      input {
        flex: 1;
        height: 100%;
        color: #666666;
        margin-left: 24rpx;
        border: none;
      }
    }
  }
  .login_btn {
    width: 100%;
    padding: 0 60rpx;
    box-sizing: border-box;
    margin-top: 60rpx;
    .for_psd {
      color: $uni-color-primary;
      width: 140rpx;
      text-align: center;
      margin: 40rpx auto;
    }
    .login_btn_n {
      width: 100%;
      height: 98rpx;
      background: $uni-color-primary;
      box-shadow: 0rpx 12rpx 24rpx 0rpx rgba(39, 155, 170, 0.2);
      display: flex;
      align-items: center;
      justify-content: center;
      color: #ffffff;
      border-radius: 50rpx;
            font-weight: 500;
            font-size: 32rpx;
    }
  }
  .deal_wrap {
    position: absolute;
    width: 100%;
    left: 0;
    text-align: center;
    bottom: 88rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    .deal {
      color: $uni-color-primary;
    }
    .checked {
      width: 48rpx;
      margin-right: 12rpx;
    }
  }
}
.modal {
  width: 690rpx;
  min-height: 920rpx;
  max-height: 720px;
  border-radius: 24rpx;
  padding: 32rpx;
}
</style>
<template>
    <view class="login">
        <view class="login_title">欢迎登录</view>
        <view class="login_title login_title2">阜宁文体中心</view>
        <view class="login_list">
            <view class="login_list_item">
                <image src="@/static/login_ic_phone@2x.png" mode="widthFix" />
                <input v-model="form.phone" maxlength="18" placeholder="请输入手机号" />
            </view>
            <!--     <view class="login_list_item">
        <image src="@/static/login_ic_password@2x.png" mode="widthFix" />
        <input v-model="form.password" type="password" placeholder="密码" />
      </view> -->
            <view class="login_list_item">
                <image src="@/static/login_ic_password@2x.png" mode="widthFix"></image>
                <input v-model="form.code" placeholder="请输入验证码" type="text" />
                <view v-if="downTime == 0" class="btn" @click="sendSms">获取验证码</view>
                <view v-else class="btn gray">{{ downTime }}</view>
            </view>
        </view>
        <view class="login_btn">
            <view class="login_btn_n" @click="onLogin">登录</view>
        </view>
    </view>
</template>
<script>
    import {
        loginPost,
        getUserInfo,
        sendSMsPost,
        ywWxAuthorize
    } from '@/api'
    import {
        mapState,
        mapMutations
    } from 'vuex'
    export default {
        name: 'login',
        data() {
            return {
                form: {
                    phone: '',
                    code: ''
                },
                downTime: 0,
                code: ''
                // code: ''
            }
        },
        onShow() {
            // return
            var that = this
            let url = window.location.href
            if (url.indexOf('code=') !== -1 || this.code) {
                let code = ''
                const query = url.split('?')
                for (const q of query) {
                    if (q.indexOf('code=') !== -1) {
                        let statusIndex = q.indexOf('&state')
                        code = q.substring(q.indexOf('code=') + 5, statusIndex)
                    }
                }
                ywWxAuthorize({
                    code: code || this.code
                }).then(res => {
                    if (res.code === 200) {
                        console.log('res', res);
                        that.$store.commit('setOpenId', res.data.openid)
                        if (res.data.token && res.data.token != '') {
                            that.$store.commit('setToken', res.data.token)
                            getUserInfo().then(ress => {
                                that.$store.commit('setUserInfo', ress.data)
                            })
                            setTimeout(() => {
                                uni.redirectTo({
                                    url: "/pages/index"
                                })
                            }, 300)
                        }
                    }
                })
            } else {
                let url = 'https://zhcg.fnwtzx.com/yunwei_h5'
                const appID = 'wx95ac1efb67f0330d'
                let uri = encodeURIComponent(url)
                let authURL =
                    `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appID}&redirect_uri=${uri}&response_type=code&scope=snsapi_base#wechat_redirect`
                window.location.href = authURL
            }
        },
        // onBackPress(options) {
        //     uni.redirectTo({
        //         url: '/pages/login/login'
        //     })
        //     return true
        // },
        methods: {
            ...mapMutations(["setToken", "setUserInfo"]),
            onLogin() {
                const {
                    form,
                    ProtocolFlag
                } = this
                if (!form.phone) return uni.showToast({
                    title: '手机号不能为空',
                    icon: 'none'
                })
                if (!form.code) return uni.showToast({
                    title: '验证码不能为空',
                    icon: 'none'
                })
                loginPost({
                    ...form,
                    openid: this.$store.state.openId
                }).then(res => {
                    if (res.code === 200) {
                        this.setToken(res.data)
                        this.showToast('登录成功')
                        getUserInfo().then(ress => {
                            this.setUserInfo(ress.data)
                            uni.redirectTo({
                                url: "/pages/index"
                            })
                        })
                    }
                })
            },
            sendSms() {
                this.downTime = 60
                let timer = setInterval(() => {
                    if (this.downTime == 0) return clearInterval(timer)
                    this.downTime = this.downTime - 1
                }, 1000)
                const {
                    form
                } = this
                sendSMsPost({
                    phone: form.phone,
                    type: 0
                }).then(res => {
                    this.showToast('短信发送成功')
                })
            },
        }
    }
</script>
<style lang="scss" scoped>
    .login {
        width: 100%;
        height: 100vh;
        display: flex;
        padding-top: 130rpx;
        box-sizing: border-box;
        align-items: center;
        flex-direction: column;
        background: linear-gradient(180deg, #C5DDFF 0%, #FFFFFF 100%);
        .login_title {
            font-weight: 500;
            font-size: 52rpx;
            color: #222222;
            margin-top: 180rpx;
            width: 100%;
            padding-left: 60rpx;
        }
        .login_title2 {
            margin-top: 10rpx;
            margin-bottom: 80rpx;
        }
        .login_list {
            width: 100%;
            padding: 0 60rpx;
            box-sizing: border-box;
            .login_list_item {
                width: 100%;
                border-radius: 50rpx;
                height: 98rpx;
                padding: 0 40rpx;
                box-sizing: border-box;
                background: #ffffff;
                margin-bottom: 40rpx;
                display: flex;
                align-items: center;
                justify-content: space-between;
                &:last-child {
                    margin-bottom: 0 !important;
                }
                image {
                    flex-shrink: 0;
                    width: 40rpx;
                    height: 40rpx;
                }
                .btn {
                    width: 145rpx;
                    color: $primaryColor;
                    text-align: center;
                }
                .gray {
                    color: #999999;
                }
                input {
                    flex: 1;
                    height: 100%;
                    color: #666666;
                    margin-left: 24rpx;
                    border: none;
                }
            }
        }
        .login_btn {
            width: 100%;
            padding: 0 60rpx;
            box-sizing: border-box;
            margin-top: 60rpx;
            .for_psd {
                color: $uni-color-primary;
                width: 140rpx;
                text-align: center;
                margin: 40rpx auto;
            }
            .login_btn_n {
                width: 100%;
                height: 98rpx;
                background: $uni-color-primary;
                box-shadow: 0rpx 12rpx 24rpx 0rpx rgba(39, 155, 170, 0.2);
                display: flex;
                align-items: center;
                justify-content: center;
                color: #ffffff;
                border-radius: 50rpx;
                font-weight: 500;
                font-size: 32rpx;
            }
        }
        .deal_wrap {
            position: absolute;
            width: 100%;
            left: 0;
            text-align: center;
            bottom: 88rpx;
            display: flex;
            justify-content: center;
            align-items: center;
            .deal {
                color: $uni-color-primary;
            }
            .checked {
                width: 48rpx;
                margin-right: 12rpx;
            }
        }
    }
    .modal {
        width: 690rpx;
        min-height: 920rpx;
        max-height: 720px;
        border-radius: 24rpx;
        padding: 32rpx;
    }
</style>
h5/pages/operation/detail.vue
@@ -2,7 +2,7 @@
    <view>
        <view class="content">
            <view class="name_wrap">
                <view class="name">{{info.deviceName}}</view>
                <view class="name">{{info.deviceName}} {{info.deviceCode || ''}}</view>
                <view class="status" v-if="info.status == 0">正常</view>
                <view class="status red" v-if="info.status == 1">损坏</view>
                <view class="status red" v-if="info.status == 2">报废</view>
@@ -15,7 +15,7 @@
            <view class="title">运维备注</view>
            <view class="file_list">
                <view class="file" v-for="item in info.multifileList">
                    <image v-if="item.type == 0" :src="item.fileurlFull" mode="widthFix"></image>
                    <image v-if="item.type == 0" :src="item.fileurlFull" mode="aspectFill"></image>
                    <video v-if="item.type == 1" :src="item.fileurlFull" :controls="false"></video>
                </view>
            </view>
@@ -99,6 +99,7 @@
            }
            image,video{
                width: 156rpx;
                height: 156rpx;
            }
        }
        .desc{
h5/pages/operation/device.vue
@@ -5,8 +5,8 @@
                <view class="la"><text class="red">*</text>选择设备</view>
                <view class="line">
                    <view class="sel_wrap" @click="showModal = true">
                        <view class="left" :class="param.deviceName ? '' : 'placeholder9'">
                            {{ param.deviceName ? param.deviceName : '请选择设备' }}
                        <view class="left" :class="(param.deviceName || param.deviceCode) ? '' : 'placeholder9'">
                            {{ (param.deviceName || param.deviceCode) ? param.deviceName ? `[${param.deviceCode}] ` + param.deviceName : `[${param.deviceCode}]` : '请选择设备' }}
                        </view>
                        <u-icon name="arrow-right" color="#999999" size="17"></u-icon>
                    </view>
@@ -118,14 +118,37 @@
                } = this
                if (!param.deviceId) return this.showToast('请先选择要维护的设备')
                this.handleP()
            },
            handleP() {
                const {
                    param,
                    fileList
                } = this
                ywDeviceCreate({
                    ...param,
                    userId: uni.getStorageSync('userInfo').id,
                    dealDate: dayjs().format('YYYY-MM-DD HH:mm:ss'),
                    multifileList: fileList
                }).then(res => {
                    this.showToast('提交成功')
                    uni.navigateBack()
                    if (param.status != 0) {
                        uni.showModal({
                            title: '温馨提示',
                            content: '设备运维结果异常,是否前往提交工单?',
                            success: function(res) {
                                if (res.confirm) {
                                    uni.redirectTo({
                                        url: '/pages/workOrder/edit'
                                    })
                                } else if (res.cancel) {
                                    uni.navigateBack()
                                }
                            }
                        });
                    }else{
                        this.showToast('提交成功')
                        uni.navigateBack()
                    }
                })
            },
            getDevice() {
@@ -145,6 +168,7 @@
                } = this
                if (!activeDevice.id) return this.showToast('请先选择设备')
                this.$set(this.param, 'deviceId', activeDevice.id)
                this.$set(this.param, 'deviceCode', activeDevice.code)
                this.$set(this.param, 'deviceName', activeDevice.name)
                this.showModal = false
            },
@@ -261,7 +285,7 @@
                            },
                            (decodeText, decodeResult) => {
                                if (decodeText) { //这里decodeText就是通过扫描二维码得到的内容
                                    this.action(decodeText) //对二维码逻辑处理
                                    this.$set(this.param, 'deviceCode', decodeText)
                                    this.stopScan(); //关闭扫码功能
                                }
                            },
@@ -408,11 +432,12 @@
    }
    .sub_btn {
        position: fixed;
        bottom: 68rpx;
        left: 40rpx;
        // position: fixed;
        // bottom: 68rpx;
        // left: 40rpx;
        width: 670rpx;
        height: 88rpx;
        margin-top: 80rpx;
        background: $primaryColor;
        box-shadow: 0rpx 8rpx 20rpx 0rpx rgba(0, 104, 255, 0.3);
        border-radius: 44rpx;
@@ -457,6 +482,7 @@
        .modal_list {
            height: calc(100% - 360rpx);
            margin-bottom: -20rpx;
            .item {
                display: flex;
h5/pages/operation/record.vue
@@ -3,7 +3,7 @@
        <view class="head_wrap">
            <view class="search_wrap">
                <image class="mr12 search" src="@/static/home/ic_search@2x.png" mode="widthFix"></image>
                <input v-model="param.deviceName" @confirm="getList()" type="text" placeholder="搜索设备名称/编号"
                <input v-model="param.deviceName" @confirm="queryList" type="text" placeholder="搜索设备名称/编号"
                    placeholder-class="placeholder9" />
            </view>
            <view class="name_wrap" @click="handleMem">
@@ -71,11 +71,18 @@
            this.$eventBus.$on('memberSel', (option) => {
                this.$set(this.param, 'userName', option.realname)
                this.$set(this.param, 'userId', option.id)
                this.list = []
                this.page = 1
                this.getList()
            })
            
        },
        methods: {
        methods: {
            queryList() {
                this.page = 1
                this.list = []
                this.getList()
            },
            getList() {
                const {
                    page,
@@ -118,7 +125,7 @@
<style lang="scss" scoped>
    .main_app {
        padding: 0 30rpx;
        padding: 30rpx;
    }
    .head_wrap {
h5/pages/polling/detail.vue
@@ -1,14 +1,16 @@
<template>
    <view class="main_app">
        <view v-if="info.status || info.status == 0" class="head_bg" :style="{
            background: `linear-gradient(180deg, ${statusM[info.status].color} 0%, rgba(247, 247, 247, 0) 100%)`
        <view v-if="info.status || info.status == 0" class="head_bg" :style="{
            background: `linear-gradient(180deg, ${statusM[info.status].color} 0%, rgba(247, 247, 247, 0) 100%)`
        }"></view>
        <view class="info">
            <image v-if="info.status == 2" class="icon" src="@/static/side/ic_dabiaoed.png" mode=""></image>
            <image v-if="info.status == 3" class="icon" src="@/static/side/ic_dabiao.png" mode=""></image>
            <view class="head">
                <view class="name">{{ info.title || info.planTitle }}</view>
                <view class="status" v-if="info.status || info.status == 0" :style="{color: statusM[info.status].color}">{{statusM[info.status].name}}</view>
                <view class="status" v-if="info.status || info.status == 0" :style="{color: statusM[info.status].color}">
                    {{statusM[info.status].name}}
                </view>
            </view>
            <view class="line">
                <view class="la">任务日期:</view>
@@ -17,7 +19,8 @@
            <view class="line">
                <view class="la">执行时间:</view>
                <view class="val" v-if="info.startDate && info.endDate">{{ info.startDate.slice(11,16) }} 至
                    {{ info.endDate.slice(11, 16) }}</view>
                    {{ info.endDate.slice(11, 16) }}
                </view>
            </view>
            <view class="line">
                <view class="la">完成情况:</view>
@@ -47,8 +50,12 @@
                </view>
            </view>
        </view>
        <view class="footer" v-if="flag">
        <view class="footer" @click="openSc" v-if="flag">
            <view class="sub_btn">扫码巡检</view>
        </view>
        <!--  -->
        <view class="reader-box" @click="stopScan" v-if="isScaning">
            <view class="reader" id="reader"></view>
        </view>
    </view>
</template>
@@ -56,34 +63,95 @@
<script>
    import {
        ywPatrolDetail,
        ywPatrolTaskRecord
    } from '@/api'
        ywPatrolTaskRecord,
        getPointRecordByCode
    } from '@/api'
    import dayjs from 'dayjs';
    import {
        Html5Qrcode
    } from 'html5-qrcode';
    export default {
        data() {
            return {
                id: '',
                info: {},
                list: [],
                flag: false,
                statusM: [
                    { color: '#4593f7', name: '待开始' },
                    { color: '#73e09a', name: '进行中' },
                    { color: '#f1a93f', name: '已超期' },
                    { color: '#b9b9b9', name: '已处理' },
                ]
                list: [],
                flag: false,
                statusM: [{
                        color: '#4593f7',
                        name: '待开始'
                    },
                    {
                        color: '#73e09a',
                        name: '进行中'
                    },
                    {
                        color: '#f1a93f',
                        name: '已超期'
                    },
                    {
                        color: '#b9b9b9',
                        name: '已处理'
                    },
                ],
                html5Qrcode: null,
                isScaning: false,
            };
        },
        onLoad(option) {
            this.id = option.id
            this.getDetail()
        },
        onShow() {
            this.getDetail()
        },
        // onShow() {
        //     this.getDetail()
        // },
        methods: {
            itemClick(item) {
                if(!this.flag) return
            openSc() {
                this.isScaning = true;
                Html5Qrcode.getCameras().then((devices) => {
                    if (devices && devices.length) {
                        this.html5Qrcode = new Html5Qrcode('reader');
                        this.html5Qrcode.start({
                                facingMode: 'environment'
                            }, {
                                focusMode: 'continuous', //设置连续聚焦模式
                                fps: 5, //设置扫码识别速度
                                qrbox: 280 //设置二维码扫描框大小
                            },
                            (decodeText, decodeResult) => {
                                if (decodeText) { //这里decodeText就是通过扫描二维码得到的内容
                                    this.stopScan(); //关闭扫码功能
                                    getPointRecordByCode({
                                        taskId: this.id,
                                        pointCode: decodeText
                                    }).then(ress => {
                                        if (ress.data) {
                                            uni.navigateTo({
                                                url: '/pages/polling/point?id=' + ress.data.id
                                            })
                                        } else {
                                            this.showToast('未匹配到巡检点,请重新扫描')
                                        }
                                    })
                                }
                            },
                            (err) => {
                                // console.log(err);  //错误信息
                            }
                        );
                    }
                });
            },
            stopScan() {
                console.log('停止扫码')
                this.isScaning = false;
                if (this.html5Qrcode) {
                    this.html5Qrcode.stop();
                }
            },
            itemClick(item) {
                if (!this.flag) return
                uni.navigateTo({
                    url: '/pages/polling/point?id=' + item.id
                })
@@ -93,8 +161,9 @@
                    id
                } = this
                ywPatrolDetail(id).then(res => {
                    this.info = res.data
                    let time = new Date(res.data.startDate.slice(0, 10) + ' 00:00:00').getTime()
                    this.info = res.data
                    let time = new Date(res.data.startDate).getTime()
                    console.log('res.data.startDate', new Date().getTime());
                    this.flag = new Date().getTime() > time
                })
                ywPatrolTaskRecord({
@@ -107,22 +176,26 @@
                    this.list = res.data.records
                })
            },
            async startScan() {
                  try {
                    const video = document.getElementById('video');
                    const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } });
                    video.srcObject = stream;
                    // 使用 QrScanner 解析
                    const qrScanner = new QrScanner(video, result => {
                      alert(`扫描结果: ${result}`);
                      qrScanner.stop(); // 停止扫码
                    });
                    qrScanner.start();
                  } catch (err) {
                    console.error('打开摄像头失败:', err);
                  }
                }
            async startScan() {
                try {
                    const video = document.getElementById('video');
                    const stream = await navigator.mediaDevices.getUserMedia({
                        video: {
                            facingMode: "environment"
                        }
                    });
                    video.srcObject = stream;
                    // 使用 QrScanner 解析
                    const qrScanner = new QrScanner(video, result => {
                        alert(`扫描结果: ${result}`);
                        qrScanner.stop(); // 停止扫码
                    });
                    qrScanner.start();
                } catch (err) {
                    console.error('打开摄像头失败:', err);
                }
            }
        }
    }
</script>
@@ -174,9 +247,10 @@
                .status {
                    color: $primaryColor;
                }
                .gray{
                    color: gray;
                }
                .gray {
                    color: gray;
                }
            }
@@ -212,9 +286,11 @@
                display: flex;
                padding: 20rpx 30rpx 0 16rpx;
                margin-bottom: 20rpx;
                .line{
                    margin-bottom: 10rpx;
                .line {
                    margin-bottom: 10rpx;
                }
                .icon {
                    width: 10rpx;
                    height: 148rpx;
@@ -238,9 +314,10 @@
                            offset-anchor: 28rpx;
                            color: $primaryColor;
                            font-weight: 400;
                        }
                        .gray{
                            color: #999999;
                        }
                        .gray {
                            color: #999999;
                        }
                    }
@@ -284,4 +361,23 @@
        }
    }
    .reader-box {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        background-color: rgba(0, 0, 0, 0.5);
    }
    .reader {
        width: 100%;
        // width: 540rpx;
        // height: 540rpx;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
</style>
h5/pages/polling/task.vue
@@ -28,23 +28,23 @@
        <!--  -->
        <scroll-view scroll-y="true" class="scroll_Y" @scrolltolower="scrolltolower">
            <view class="list">
                <view class="item" v-for="item in list" @click="itemClick(item)">
                    <image v-if="item.status == 0 || item.status == 1" src="@/static/side/xunjianed.png" class="icon"></image>
                    <image v-else src="@/static/side/xunjian.png" class="icon"></image>
                <view class="item" v-for="item in list">
                    <image @click="itemClick(item)" v-if="item.status == 0 || item.status == 1" src="@/static/side/xunjianed.png" class="icon"></image>
                    <image @click="itemClick(item)" v-else src="@/static/side/xunjian.png" class="icon"></image>
                    <view class="content">
                        <view class="name_wrap line">
                            <view class="name">{{item.planTitle}}</view>
                            <view class="status" :class="{
                            <view class="name" @click="itemClick(item)">{{item.planTitle}}</view>
                            <view class="status" @click="itemClick(item)" :class="{
                                green: item.status == 1,
                                red: item.status == 2,
                                gray: item.status == 3 || item.status == 4
                            }">{{statusM[item.status]}}</view>
                        </view>
                        <view class="line" v-if="item.startDate">任务日期:{{ item.startDate.slice(0, 11) }}</view>
                        <view class="line">执行时间:{{ item.startDate.slice(11, 16) }} 至 {{ item.endDate.slice(11, 16) }}</view>
                        <view class="line" @click="itemClick(item)" v-if="item.startDate">任务日期:{{ item.startDate.slice(0, 11) }}</view>
                        <view class="line" @click="itemClick(item)">执行时间:{{ item.startDate.slice(11, 16) }} 至 {{ item.endDate.slice(11, 16) }}</view>
                        <view class="line">
                            <view>完成情况:{{item.finishNum || 0}}/{{item.patrolNum}}</view>
                            <view class="btn">
                            <view @click="itemClick(item)">完成情况:{{item.finishNum || 0}}/{{item.patrolNum}}</view>
                            <view v-if="param.queryStatus == '0,1'" class="btn" @click="openSc(item)">
                                <image src="@/static/side/ic_saoma@2x.png" class="saoma" mode=""></image>
                                <view>扫码巡检</view>
                            </view>
@@ -54,14 +54,22 @@
            </view>
        </scroll-view>
        <!--  -->
        <!--  -->
        <!--  -->
        <view class="reader-box" @click="stopScan" v-if="isScaning">
            <view class="reader" id="reader"></view>
        </view>
    </view>
</template>
<script>
    import {
        ywPatrolTaskPost
    } from '@/api'
        ywPatrolTaskPost,
        getPointRecordByCode
    } from '@/api'
    import {
        Html5Qrcode
    } from 'html5-qrcode';
    export default {
        data() {
            return {
@@ -79,13 +87,60 @@
                    2: '已超期',
                    3: '已完成',
                    4: '已取消',
                }
                },
                html5Qrcode: null,
                isScaning: false,
                // activeItem: {}
            };
        },
        onLoad() {
            this.getList()
        },
        methods: {
            openSc(item) {
                this.isScaning = true;
                Html5Qrcode.getCameras().then((devices) => {
                    if (devices && devices.length) {
                        this.html5Qrcode = new Html5Qrcode('reader');
                        this.html5Qrcode.start({
                                facingMode: 'environment'
                            }, {
                                focusMode: 'continuous', //设置连续聚焦模式
                                fps: 5, //设置扫码识别速度
                                qrbox: 280 //设置二维码扫描框大小
                            },
                            (decodeText, decodeResult) => {
                                if (decodeText) { //这里decodeText就是通过扫描二维码得到的内容
                                    this.stopScan(); //关闭扫码功能
                                    getPointRecordByCode({
                                        taskId: item.id,
                                        pointCode: decodeText
                                    }).then(ress=> {
                                        if(ress.data){
                                            uni.navigateTo({
                                                url: '/pages/polling/point?id=' + ress.data.id
                                            })
                                        }else{
                                            this.showToast('未匹配到巡检点,请重新扫描')
                                        }
                                    })
                                }
                            },
                            (err) => {
                                // console.log(err);  //错误信息
                            }
                        );
                    }
                });
            },
            stopScan() {
                console.log('停止扫码')
                this.isScaning = false;
                if (this.html5Qrcode) {
                    this.html5Qrcode.stop();
                }
            },
            scrolltolower() {
                const {
                    total,
@@ -300,4 +355,23 @@
            }
        }
    }
    .reader-box {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        background-color: rgba(0, 0, 0, 0.5);
    }
    .reader {
        width: 100%;
        // width: 540rpx;
        // height: 540rpx;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
</style>
h5/pages/workOrder/detail.vue
@@ -4,7 +4,7 @@
            <view class="title">
                <text>{{ info.projectName }}/{{ info.buildingName }}/{{info.roomNum || info.floorName}}</text>
                <text class="status" v-if="info.dealStatus == 0">待处理</text>
                <text class="status" v-if="info.dealStatus == 1">已指派</text>
                <text class="status" v-if="info.dealStatus == 1">待处理</text>
                <text class="status gray" v-if="info.dealStatus == 2">已处理</text>
            </view>
            <view class="desc">{{ info.content }}</view>
@@ -58,8 +58,8 @@
            </view>
        </view>
        <!--  -->
        <view class="btns" v-if="info.dealStatus == 0">
            <view class="btn">
        <view class="btns" v-if="info.dealStatus == 0 || (info.dealUserId === userInfo.id && info.dealStatus == 1)">
            <view class="btn" @click="handleCall">
                <image src="@/static/side/phoneed.png" class="icon"></image>
                <text>上报人</text>
            </view>
@@ -135,7 +135,8 @@
                info: {},
                showUpload: false,
                isShowHandle: false,
                isShowHandleDate: false,
                isShowHandleDate: false,
                userInfo: uni.getStorageSync('userInfo') || {},
                handleParam: {},
                dealFileList: []
            };
@@ -159,6 +160,12 @@
                        uni.navigateBack()
                    }
                })
            },
            handleCall() {
                const { info } = this
                uni.makePhoneCall({
                    phoneNumber: info.creatorMobile
                });
            },
            getDetail() {
                ywWorkorderD(this.id).then(res => {
h5/pages/workOrder/edit.vue
@@ -142,7 +142,11 @@
                const {
                    param,
                    fileList
                } = this
                } = this
                if (!param.projectId) return this.showToast('请选择完整的区域')
                if (!param.buildingId) return this.showToast('请选择完整的区域')
                if (!param.floorName && !param.roomNum) return this.showToast('请选择完整的区域')
                if (!param.cateName) return this.showToast('请选择工单分类')
                ywWorkorderCreate({
                    ...param,
                    // roomId: '',
@@ -445,11 +449,12 @@
    }
    .sub_btn {
        position: fixed;
        bottom: 68rpx;
        left: 40rpx;
        // position: fixed;
        // bottom: 68rpx;
        // left: 40rpx;
        width: 670rpx;
        height: 88rpx;
        height: 88rpx;
        margin-top: 80rpx;
        background: $primaryColor;
        box-shadow: 0rpx 8rpx 20rpx 0rpx rgba(0, 104, 255, 0.3);
        border-radius: 44rpx;
h5/pages/workOrder/list.vue
@@ -73,7 +73,7 @@
                page: 1,
            };
        },
        onShow() {
        onLoad() {
            this.getList()
        },
        methods: {
@@ -139,7 +139,7 @@
<style lang="scss" scoped>
    .main_app {
        padding: 0 30rpx;
        padding: 30rpx;
    }
    .tabs {
h5/utils/config.js
@@ -1,7 +1,6 @@
export const baseUrl = 'gateway_interface/'
 // export const baseUrl = 'gateway_interface/'
// export const baseUrl = 'http://192.168.0.173/gateway_interface/'
// export const baseUrl = 'http://10.50.250.253:8088/gateway_interface/'
export const baseUrl = 'https://zhcg.fnwtzx.com/gateway_interface/'
export const uploadAvatar = `${baseUrl}visitsAdmin/cloudService/web/public/uploadFtp.do`
export const uploadUrl = `${baseUrl}visitsAdmin/cloudService/public/uploadBatch`
server/system_gateway/src/main/java/com/doumee/api/gateway/JwtAuthController.java
@@ -16,6 +16,7 @@
import com.doumee.service.system.SystemUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.validation.annotation.Validated;
@@ -157,12 +158,10 @@
    public ApiResponse<String> logout(@RequestHeader(Constants.HEADER_USER_TOKEN) String oldToken){
        try {
             jwtTokenUtil.logout(oldToken);
        }catch (BusinessException e){
            return ApiResponse.failed(e.getCode(),e.getMessage());
        }catch (Exception e){
            e.printStackTrace();
            return ApiResponse.failed(ResponseStatus.SERVER_ERROR);
        }
        return ApiResponse.success(null);
server/system_gateway/src/main/resources/application-pro.yml
@@ -1,12 +1,17 @@
spring:
  # 数据源配置
  datasource:
    url: jdbc:mysql://localhost:3306/funingyunwei?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: funing@2024
    url: jdbc:mysql://rm-bp136n33jr035pbfl3o.mysql.rds.aliyuncs.com:3306/funingyunwei?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: zhcg
    password: Fnwtzx@1127$dmtt
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
  redis:
    #    database: 0
    host: 127.0.0.1
    port: 6379
    password:
    timeout: 5000      # 连接池中的最小空闲连接
  jackson:
    time-zone: GMT+8
    date-format: yyyy-MM-dd HH:mm:ss
server/system_gateway/src/main/resources/bootstrap.yml
@@ -1,6 +1,6 @@
spring:
  profiles:
    active: test
    active: pro
  application:
    name: system_gateway
  # 安全配置
server/system_service/src/main/java/com/doumee/cloud/SystemUserCloudController.java
@@ -122,8 +122,8 @@
    @ApiOperation("查询所有内部人员用户")
    @PostMapping("/findInternalList")
    @CloudRequiredPermission("system:user:query")
    public ApiResponse<List<SystemUser>> findInternalList () {
        return ApiResponse.success(systemUserService.findInternalList());
    public ApiResponse<List<SystemUser>> findInternalList (@RequestBody SystemUser systemUser) {
        return ApiResponse.success(systemUserService.findInternalList(systemUser));
    }
    @ApiOperation("根据ID查询")
server/system_service/src/main/java/com/doumee/config/jwt/JwtTokenUtil.java
@@ -5,6 +5,7 @@
import com.doumee.core.model.LoginUserInfo;
import com.doumee.core.utils.Constants;
import com.doumee.core.utils.HttpsUtil;
import com.doumee.service.system.SystemLoginService;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
@@ -36,6 +37,9 @@
    private JwtProperties jwtProperties;
    @Autowired
    private SystemDictDataBiz systemDictDataBiz ;
    @Autowired
    private SystemLoginService systemLoginService;
    /**
     * 生成token令牌
@@ -137,7 +141,7 @@
                HttpsUtil.get(url+"?token="+loginUserInfo.getHkMenuToken(),true);
            }
            redisTemplate.delete(Constants.REDIS_TOKEN_KEY+token);//删除老的token
            systemLoginService.cleanOpenid(loginUserInfo.getId());
        } catch (Exception e) {
            e.printStackTrace();
        }
server/system_service/src/main/java/com/doumee/dao/system/dto/LoginDTO.java
@@ -19,6 +19,10 @@
    @ApiModelProperty(value = "用户名")
    private String username;
    @ApiModelProperty(value = "微信openId")
    private String openid;
    @NotBlank(message = "密码不能为空")
    @ApiModelProperty(value = "密码")
    private String password;
server/system_service/src/main/java/com/doumee/dao/system/dto/LoginPhoneDTO.java
@@ -18,6 +18,12 @@
    @NotBlank(message = "手机号不能为空")
    @ApiModelProperty(value = "手机号")
    private String phone;
    @ApiModelProperty(value = "微信openId")
    private String openid;
    @NotBlank(message = "验证码不能为空")
    @ApiModelProperty(value = "验证码")
    private String code;
server/system_service/src/main/java/com/doumee/dao/system/model/SystemUser.java
@@ -102,6 +102,8 @@
    @ApiModelProperty(value = "是否已删除", hidden = true)
    private Boolean deleted;
    @ApiModelProperty(value = "0 启用 1 禁用")
    private Integer status;
    @ApiModelProperty(value = "企业编码(关联company)")
server/system_service/src/main/java/com/doumee/service/system/SystemLoginService.java
@@ -35,4 +35,6 @@
     * @return
     */
    String loginByUserId(Integer userId);
    void cleanOpenid(Integer userId);
}
server/system_service/src/main/java/com/doumee/service/system/SystemUserService.java
@@ -86,7 +86,7 @@
     * 查询所有内部人员列表
     * @return
     */
    List<SystemUser> findInternalList();
    List<SystemUser> findInternalList(SystemUser systemUser);
    /**
     * 条件统计
server/system_service/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java
@@ -1,6 +1,7 @@
package com.doumee.service.system.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.doumee.config.jwt.JwtTokenUtil;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.model.LoginUserInfo;
@@ -11,6 +12,7 @@
import com.doumee.dao.business.dao.SmsEmailMapper;
import com.doumee.dao.business.model.Company;
import com.doumee.dao.business.model.SmsEmail;
import com.doumee.dao.system.SystemUserMapper;
import com.doumee.dao.system.dto.LoginByOpenidDTO;
import com.doumee.dao.system.dto.LoginDTO;
import com.doumee.dao.system.dto.LoginPhoneDTO;
@@ -50,6 +52,9 @@
    @Autowired
    private SmsEmailMapper smsEmailMapper;
    @Autowired
    private SystemUserMapper systemUserMapper;
    @Lazy
    @Autowired
@@ -83,7 +88,7 @@
        loginLog.setLoginTime(new Date());
        loginLog.setSystemVersion(systemVersion);
        loginLog.setIp(Utils.User_Client.getIP(request));
        loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp()));
//        loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp()));
        loginLog.setPlatform(Utils.User_Client.getPlatform(request));
        loginLog.setClientInfo(Utils.User_Client.getBrowser(request));
        loginLog.setOsInfo(Utils.User_Client.getOS(request));
@@ -124,7 +129,7 @@
        loginLog.setLoginUsername(dto.getUsername());
        loginLog.setLoginTime(new Date());
        loginLog.setSystemVersion(systemVersion);
        loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp()));
//        loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp()));
        if(request!=null&&request.getHeaders()!=null && request.getHeaders().size()>0){
            loginLog.setIp(Utils.User_Client.getIP(request));
            loginLog.setPlatform(Utils.User_Client.getPlatform(request));
@@ -164,6 +169,7 @@
        if(Objects.nonNull(user.getCompanyId())){
            company = companyMapper.selectById(user.getCompanyId());
        }
        dealOpenIdBiz(user,dto.getOpenid());
        // 获取登录用户信息
        List<SystemRole> roles = systemRoleService.findByUserId(user.getId());
        List<SystemPermission> permissions = systemPermissionService.findByUserId(user.getId());
@@ -178,6 +184,21 @@
    }
    private void dealOpenIdBiz(SystemUser user, String openid) {
        if(StringUtils.isNotBlank(openid)){
            //如果openId不为空,绑定该用户openid
            systemUserMapper.update(null,new UpdateWrapper<SystemUser>().lambda()
                    .set(SystemUser::getOpenid,null)
                    .eq(SystemUser::getType,user.getType())
                    .eq(SystemUser::getOpenid,openid)
            );
            systemUserMapper.update(null,new UpdateWrapper<SystemUser>().lambda()
                    .set(SystemUser::getOpenid,openid)
                    .eq(SystemUser::getId,user.getId()));
        }
    }
@@ -187,7 +208,7 @@
        loginLog.setLoginUsername(dto.getPhone());
        loginLog.setLoginTime(new Date());
        loginLog.setSystemVersion(systemVersion);
        loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp()));
//        loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp()));
        if(request!=null&&request.getHeaders()!=null && request.getHeaders().size()>0){
            loginLog.setIp(Utils.User_Client.getIP(request));
            loginLog.setPlatform(Utils.User_Client.getPlatform(request));
@@ -239,6 +260,9 @@
        if(Objects.nonNull(user.getCompanyId())){
            company = companyMapper.selectById(user.getCompanyId());
        }
        dealOpenIdBiz(user,dto.getOpenid());
        // 获取登录用户信息
        List<SystemRole> roles = systemRoleService.findByUserId(user.getId());
        List<SystemPermission> permissions = systemPermissionService.findByUserId(user.getId());
@@ -259,7 +283,7 @@
        loginLog.setLoginUsername(dto.getUsername());
        loginLog.setLoginTime(new Date());
        loginLog.setSystemVersion(systemVersion);
        loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp()));
//        loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp()));
        if(request!=null&&request.getHeaders()!=null && request.getHeaders().size()>0){
            loginLog.setIp(Utils.User_Client.getIP(request));
            loginLog.setPlatform(Utils.User_Client.getPlatform(request));
@@ -289,6 +313,15 @@
    }
    @Override
    public void cleanOpenid(Integer userId){
        systemUserMapper.update(null,new UpdateWrapper<SystemUser>().lambda()
                .set(SystemUser::getOpenid,null)
                .eq(SystemUser::getId,userId)
        );
    }
    /**
     * 内部人员 与 司机 根据code查询openId后进行登录接口
     * @return
@@ -298,7 +331,7 @@
        SystemLoginLog loginLog = new SystemLoginLog();
        loginLog.setLoginTime(new Date());
        loginLog.setSystemVersion(systemVersion);
        loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp()));
//        loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp()));
        loginLog.setServerIp(Utils.Server.getIP());
        // 根据用户名查询用户对象
server/system_service/src/main/java/com/doumee/service/system/impl/SystemUserServiceImpl.java
@@ -235,12 +235,13 @@
    @Override
    public List<SystemUser> findInternalList() {
    public List<SystemUser> findInternalList(SystemUser systemUser) {
        MPJLambdaWrapper<SystemUser> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.selectAll(SystemUser.class);
        queryWrapper.eq(SystemUser::getDeleted, Constants.ZERO);
        queryWrapper.leftJoin(Company.class,Company::getId,SystemUser::getCompanyId);
        queryWrapper.eq(Company::getType,Constants.ONE);
        queryWrapper.like(Objects.nonNull(systemUser)&&StringUtils.isNotBlank(systemUser.getRealname()),SystemUser::getRealname,systemUser.getRealname());
        queryWrapper.orderByDesc(SystemUser::getCreateTime);
        List<SystemUser> result = systemUserJoinMapper.selectJoinList( SystemUser.class, queryWrapper);
        return result;
server/system_timer/src/main/resources/application-pro.yml
@@ -1,9 +1,9 @@
spring:
  # 数据源配置
  datasource:
    url: jdbc:mysql://localhost:3306/funingyunwei?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: funing@2024
    url: jdbc:mysql://rm-bp136n33jr035pbfl3o.mysql.rds.aliyuncs.com:3306/funingyunwei?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: zhcg
    password: Fnwtzx@1127$dmtt
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
server/system_timer/src/main/resources/bootstrap.yml
@@ -1,6 +1,6 @@
spring:
  profiles:
    active: dev
    active: pro
  application:
    name: systemTimer
    # 安全配置
server/visits/admin_timer/src/main/java/com/doumee/api/WxTokenTimerController.java
@@ -42,6 +42,7 @@
     */
    @Value("${debug_model}")
    private Boolean timing;
    @ApiOperation("开启定时更新微信公众号accesstoken")
    @GetMapping("/updateWxAccessToken")
    public ApiResponse updateWxAccessToken() {
@@ -54,7 +55,6 @@
        String url = WXConstant.GET_ACCESS_TOKEN_URL.replace("APPID",appId).replace("APPSECRET",appSecret);
        String response = HttpsUtil.get(url,false);
        JSONObject json = JSONObject.parseObject(response);
        System.out.println(json);
        SystemDictData systemDictData =  systemDictDataBiz.queryByCode(Constants.WX_PLATFORM,Constants.WX_PLATFORM_ACCESS_TOKEN);
        if(!Objects.isNull(systemDictData)){
            systemDictData.setCode(json.getString("access_token"));
server/visits/admin_timer/src/main/java/com/doumee/api/YwTimerController.java
@@ -1,7 +1,10 @@
package com.doumee.api;
import com.alibaba.fastjson.JSONObject;
import com.doumee.biz.system.SystemDictDataBiz;
import com.doumee.core.model.ApiResponse;
import com.doumee.core.utils.HttpsUtil;
import com.doumee.core.wx.WXConstant;
import com.doumee.dao.business.model.YwContract;
import com.doumee.service.business.PlatformJobService;
import com.doumee.service.business.YwContractBillService;
@@ -52,18 +55,15 @@
        return ApiResponse.success("定时处理合同过期与执行中");
    }
    public static void main(String[] args) {
        String url = WXConstant.GET_ACCESS_TOKEN_URL.replace("APPID","wx95ac1efb67f0330d")
                .replace("APPSECRET","f228b9e3b49a37b881b51431a483c939");
        String response = HttpsUtil.get(url,false);
        JSONObject json = JSONObject.parseObject(response);
        System.out.println(json);
    }
}
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/SmsEmailColudController.java
@@ -56,5 +56,4 @@
        return ApiResponse.success("操作成功");
    }
}
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/YwContractCloudController.java
@@ -103,6 +103,7 @@
    public ApiResponse<List<YwContract>> list (@RequestBody YwContract model,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        return ApiResponse.success(ywContractService.findList(model));
    }
    @ApiOperation("根据退租日期查询账单数据")
    @PostMapping("/findForBills")
    @CloudRequiredPermission("business:ywcontract:query")
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/YwPatrolSchemeCloudController.java
@@ -101,4 +101,7 @@
    public ApiResponse findById(@PathVariable Integer id,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        return ApiResponse.success(ywPatrolSchemeService.findById(id));
    }
}
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/YwPatrolTaskRecordController.java
@@ -100,6 +100,13 @@
        return ApiResponse.success(null);
    }
    @ApiOperation("扫码获取巡检点任务信息")
    @PostMapping("/getPointRecordByCode")
    @CloudRequiredPermission("business:ywpatroltaskrecord:update")
    public ApiResponse<YwPatrolTaskRecord> getPointRecordByCode(@RequestBody YwPatrolTaskRecord ywPatrolTaskRecord,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
        return ApiResponse.success("查询成功",ywPatrolTaskRecordService.getPointRecordByCode(ywPatrolTaskRecord));
    }
}
server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/web/VisitorWebController.java
@@ -71,6 +71,19 @@
    }
    @ApiOperation(value = "访客微信授权 - 阜宁运维", notes = "访客微信授权获取openId")
    @GetMapping("/ywWxAuthorize")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "String", name = "code", value = "授权码", required = true),
            @ApiImplicitParam(paramType = "query", dataType = "Integer", name = "source", value = "来源:0=司机;1=访客;2=内部员工", required = true)
    })
    public ApiResponse<WxAuthorizeVO> ywWxAuthorize(@RequestParam String code) {
        WxAuthorizeVO wxAuthorizeVO =  memberService.ywWxAuthorize(code);
        return ApiResponse.success("查询成功",wxAuthorizeVO);
    }
    @ApiOperation(value = "查询被访问人信息", notes = "查询被访问人信息")
    @PostMapping("/getVisitedMember")
    public ApiResponse<List<MemberVO>> getVisitedMember(@Valid @RequestBody CheckVisitedDTO checkVisitedDTO) {
server/visits/dmvisit_admin/src/main/resources/bootstrap.yml
@@ -1,6 +1,6 @@
spring:
  profiles:
    active: test
    active: pro
  application:
    name: visitsAdmin
    # 安全配置
server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/YwPatrolTaskRecord.java
@@ -109,6 +109,11 @@
    @TableField(exist = false)
    private String content;
    @ApiModelProperty(value = "巡检点编码")
    @TableField(exist = false)
    private String pointCode;
    @ApiModelProperty(value = "附件列表")
    @TableField(exist = false)
    private List<Multifile> multifileList;
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/MemberService.java
@@ -176,6 +176,7 @@
     */
    WxAuthorizeVO wxAuthorize(String code,Integer source);
    WxAuthorizeVO ywWxAuthorize(String code);
    List<MemberVO> getVisitedMember(CheckVisitedDTO checkVisitedDTO);
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/YwPatrolTaskRecordService.java
@@ -99,4 +99,6 @@
    void patrolData(YwPatrolTaskRecord ywPatrolTaskRecord);
    YwPatrolTaskRecord getDetail(Integer id);
    YwPatrolTaskRecord getPointRecordByCode(YwPatrolTaskRecord bean);
}
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
@@ -49,6 +49,7 @@
import com.doumee.service.business.impl.hksync.ferp.HkSyncOrgUserToHKServiceImpl;
import com.doumee.service.system.SystemLoginService;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
@@ -73,6 +74,7 @@
 * @date 2023/11/30 15:33
 */
@Service
@Slf4j
public class MemberServiceImpl implements MemberService {
    @Autowired
@@ -1762,6 +1764,49 @@
    /**
     * 微信授权接口
     * @param code
     * @return
     */
    @Override
    public WxAuthorizeVO ywWxAuthorize(String code){
        if(StringUtils.isBlank(code)){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        String appId = systemDictDataBiz.queryByCode(Constants.WX_PLATFORM,Constants.WX_PLATFORM_APPID).getCode();
        String appSecret = systemDictDataBiz.queryByCode(Constants.WX_PLATFORM,Constants.WX_PLATFORM_SECRET).getCode();
        String getTokenUrl = WXConstant.GET_USER_INFO_URL.replace("CODE", code)
                .replace("APPID", appId).replace("SECRET", appSecret);
        log.error("=========================getTokenUrl=====================" + getTokenUrl);
        JSONObject tokenJson = JSONObject.parseObject(HttpsUtil.get(getTokenUrl,true));
        log.error("=========================tokenJson=====================" + tokenJson);
        String openId = "";
        WxAuthorizeVO wxAuthorizeVO = new WxAuthorizeVO();
        if(Objects.nonNull(tokenJson)&&!Objects.isNull(tokenJson.get("access_token"))){
            openId = tokenJson.getString("openid");
        }else{
            if(StringUtils.isBlank(openId)){
                return wxAuthorizeVO;
            }
        }
        wxAuthorizeVO.setOpenid(openId);
        //根据openId 查询用户信息
        SystemUser user = systemUserMapper.selectOne(new QueryWrapper<SystemUser>().lambda()
                .eq(SystemUser::getOpenid,openId)
                .eq(SystemUser::getDeleted,Boolean.FALSE)
                .last(" limit 1 "));
        if(!Objects.isNull(user)){
            String token = systemLoginService.loginByUserId(user.getId());
            wxAuthorizeVO.setToken(token);
        }
        return wxAuthorizeVO;
    }
    @Override
    public List<MemberVO> getVisitedMember(CheckVisitedDTO checkVisitedDTO){
        List<Member> memberList = memberJoinMapper.selectJoinList(Member.class,new MPJLambdaWrapper<Member>()
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/SmsEmailServiceImpl.java
@@ -15,6 +15,8 @@
import com.doumee.dao.business.dao.SmsConfigMapper;
import com.doumee.dao.business.dao.SmsEmailMapper;
import com.doumee.dao.business.model.*;
import com.doumee.dao.system.SystemUserMapper;
import com.doumee.dao.system.model.SystemUser;
import com.doumee.service.business.SmsEmailService;
import com.doumee.service.business.third.EmayService;
import org.apache.commons.lang3.StringUtils;
@@ -44,6 +46,8 @@
    private EmayService emayService;
    @Autowired
    private SmsConfigMapper smsConfigMapper;
    @Autowired
    private SystemUserMapper systemUserMapper;
    @Value("${debug_model}")
    private boolean debugModel;
@@ -86,6 +90,10 @@
        if(StringUtils.isBlank(smsEmail.getPhone())){
            throw  new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        //根据手机号查询用户
        if(systemUserMapper.selectCount(new QueryWrapper<SystemUser>().lambda().eq(SystemUser::getMobile,smsEmail.getPhone()))==Constants.ZERO){
            throw  new BusinessException(ResponseStatus.SERVER_ERROR.getCode(),"对不起,手机号无效请检查后重试!");
        };
        String nowDate = DateUtil.getFomartDate(new Date(),"yyyy-MM-dd HH:mm:ss");
        if(smsEmailMapper.selectCount(new QueryWrapper<SmsEmail>().lambda()
                .eq(SmsEmail::getPhone,smsEmail.getPhone())
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwContractBillServiceImpl.java
@@ -434,7 +434,7 @@
                for (String codeDate:codeDateSet) {
                    //获取当前日期的数据
                    List<YwContractBill> codeDateBillList =
                            ywContractBillList.stream().filter(i->i.getCodeDate().equals(codeDate)).collect(Collectors.toList());
                            ywContractBillList.stream().filter(i->StringUtils.isNotBlank(i.getCodeDate()) && i.getCodeDate().equals(codeDate)).collect(Collectors.toList());
                    if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isEmpty(codeDateBillList)){
                        continue;
                    }
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwContractServiceImpl.java
@@ -89,7 +89,6 @@
        }else{
            model.setStatus(Constants.TWO);
        }
        model.setStatus(Constants.ZERO);//待执行
        model.setRemark(getRemarlByParam(model));
        ywContractMapper.insert(model);
        dealDetailListBiz(model);//处理条款信息
@@ -468,8 +467,8 @@
                    }else if(fee.compareTo(new BigDecimal(0)) < 0){
                        //如果账单还有款待收,则保持状态不变
                    }
                    b.setReceivableFee(editBill.getReceivableFee());
                }
                b.setReceivableFee(editBill.getReceivableFee());
                b.setEditDate(param.getEditDate());
                b.setEditor(param.getEditor());
                b.setBtActDate(param.getBtActDate());
@@ -701,13 +700,19 @@
        }
        int num =1;
        for(int i=0;i<billList1.size();i++){
            if(Constants.formatBigdecimal(billList1.get(i).getReceivableFee()).compareTo(new BigDecimal(0)) == 0){
                billList1.get(i).setPayStatus(Constants.ONE);
            }
            if(Constants.equalsInteger(billList1.get(i).getCostType(),Constants.ZERO)){
                billList1.get(i).setSortnum(num);
                num++;
            }
        }
        for(int i=0;i<billList2.size();i++){
            if(Constants.equalsInteger(billList1.get(i).getCostType(),Constants.ONE)) {
            if(Constants.formatBigdecimal(billList2.get(i).getReceivableFee()).compareTo(new BigDecimal(0)) == 0){
                billList2.get(i).setPayStatus(Constants.ONE);
            }
            if(Constants.equalsInteger(billList2.get(i).getCostType(),Constants.ONE)) {
                billList2.get(i).setSortnum(num);
                num++;
            }
@@ -1329,9 +1334,13 @@
        if(model.getBillList()!=null && model.getBillList().size()>0){
            for(YwContractBill bill: model.getBillList()){
                //付款状态:0=待收款;1=已结清;2=部分结清;3=待付款;4=待退款;5=已关闭
                if( Constants.formatBigdecimal(bill.getReceivableFee()).compareTo(new BigDecimal(0)) ==0){
                    //如果还没开始,账单直接关闭
                    continue;
                }
                if(Constants.equalsInteger(bill.getPayStatus(),Constants.ZERO)
                        ||Constants.equalsInteger(bill.getPayStatus(),Constants.THREE)){
                    if(bill.getStartDate().getTime()>nowEnd){
                    if(bill.getStartDate().getTime()>nowEnd ){
                        //如果还没开始,账单直接关闭
                        continue;
                    }
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwDeviceRecordServiceImpl.java
@@ -52,7 +52,6 @@
        if(Objects.isNull(ywDeviceRecord)
        || Objects.isNull(ywDeviceRecord.getDeviceId())
        || Objects.isNull(ywDeviceRecord.getStatus())
        || StringUtils.isBlank(ywDeviceRecord.getContent())
        ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwPatrolSchemeServiceImpl.java
@@ -61,12 +61,16 @@
                ||Objects.isNull(ywPatrolScheme.getStartDate())
                ||Objects.isNull(ywPatrolScheme.getEndDate())
                ||Objects.isNull(ywPatrolScheme.getCircleType())
                ||StringUtils.isBlank(ywPatrolScheme.getStartTime())
                ||StringUtils.isBlank(ywPatrolScheme.getEndTime())
                || (!Constants.equalsInteger(ywPatrolScheme.getCircleType(),Constants.ZERO) &&StringUtils.isBlank(ywPatrolScheme.getCircleDays()))
        ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        if(StringUtils.isBlank(ywPatrolScheme.getStartTime())){
            ywPatrolScheme.setStartTime("00:00:00");
        }
        if(StringUtils.isBlank(ywPatrolScheme.getEndTime())){
            ywPatrolScheme.setEndTime("23:59:59");
        }
        LoginUserInfo loginUserInfo = ywPatrolScheme.getLoginUserInfo();
        ywPatrolScheme.setCreateDate(new Date());
        ywPatrolScheme.setCreator(loginUserInfo.getId());
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwPatrolTaskRecordServiceImpl.java
@@ -188,17 +188,24 @@
        if(ywPatrolTaskRecordMapper.selectCount(new QueryWrapper<YwPatrolTaskRecord>().lambda()
                .eq(YwPatrolTaskRecord::getTaskId,ywPatrolTask.getId())
                .eq(YwPatrolTaskRecord::getStatus,Constants.ZERO)
                .ne(YwPatrolTaskRecord::getId,ywPatrolTaskRecord.getId()))==Constants.ZERO){
            ywPatrolTask.setStatus(Constants.THREE);
            ywPatrolTaskMapper.update(null,new UpdateWrapper<YwPatrolTask>().lambda()
                    .eq(YwPatrolTask::getId,ywPatrolTask.getId())
                    .set(YwPatrolTask::getStatus,Constants.THREE)
                    .set(YwPatrolTask::getEditDate,DateUtil.getCurrDateTime())
                    .set(YwPatrolTask::getDealDate,DateUtil.getCurrDateTime())
                    .set(YwPatrolTask::getDealUserId,loginUserInfo.getId())
                    .set(YwPatrolTask::getEditor,loginUserInfo.getId())
            );
        }else{
            ywPatrolTask.setStatus(Constants.ONE);
            ywPatrolTaskMapper.update(null,new UpdateWrapper<YwPatrolTask>().lambda()
                    .eq(YwPatrolTask::getId,ywPatrolTask.getId())
                    .set(YwPatrolTask::getStatus,Constants.ONE)
                    .set(YwPatrolTask::getEditDate,DateUtil.getCurrDateTime())
                    .set(YwPatrolTask::getEditor,loginUserInfo.getId())
            );
        }
        //查询是否存在其他未
       ywPatrolTaskMapper.update(null,new UpdateWrapper<YwPatrolTask>().lambda().eq(YwPatrolTask::getId,ywPatrolTask.getId())
               .set(YwPatrolTask::getStatus,ywPatrolTask.getStatus())
               .set(YwPatrolTask::getEditDate,DateUtil.getCurrDateTime())
               .set(YwPatrolTask::getEditor,loginUserInfo.getId())
       );
        //附件数据
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(ywPatrolTaskRecord.getMultifileList())){
            for (Multifile multifile:ywPatrolTaskRecord.getMultifileList()) {
@@ -221,6 +228,58 @@
    @Override
    @Transactional(rollbackFor = {Exception.class,BusinessException.class})
    public YwPatrolTaskRecord getPointRecordByCode(YwPatrolTaskRecord bean) {
        if(Objects.isNull(bean)
        || Objects.isNull(bean.getTaskId())
        || StringUtils.isBlank(bean.getPointCode())){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        YwPatrolTaskRecord ywPatrolTaskRecord = ywPatrolTaskRecordMapper.selectJoinOne(YwPatrolTaskRecord.class,new MPJLambdaWrapper<YwPatrolTaskRecord>()
                .selectAll(YwPatrolTaskRecord.class)
                .selectAs(YwPatrolPoint::getName,YwPatrolTaskRecord::getPointName)
                .selectAs(YwPatrolPoint::getContent,YwPatrolTaskRecord::getContent)
                .selectAs(SystemUser::getRealname,YwPatrolTaskRecord::getRealname)
                .selectAs(Company::getName,YwPatrolTaskRecord::getCompanyName)
                .leftJoin(YwPatrolPoint.class,YwPatrolPoint::getId,YwPatrolTaskRecord::getPointId)
                .leftJoin(SystemUser.class,SystemUser::getId,YwPatrolTaskRecord::getDealUserId)
                .leftJoin(Company.class,Company::getId,SystemUser::getCompanyId)
                .eq(YwPatrolScheme::getIsdeleted, Constants.ZERO)
                .eq(YwPatrolPoint::getCode,bean.getPointCode())
                .eq(YwPatrolTaskRecord::getTaskId,bean.getTaskId())
                .orderByDesc(YwPatrolScheme::getCreateDate)
                .last(" limit 1 ")
        );
        if(Objects.isNull(ywPatrolTaskRecord)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"未匹配到巡检点!");
        }
        //附件数据
        List<Multifile> multifileList = multifileMapper.selectJoinList(Multifile.class,new MPJLambdaWrapper<Multifile>()
                .selectAll(Multifile.class)
                .selectAs(SystemUser::getRealname,Multifile::getUserName)
                .leftJoin(SystemUser.class,SystemUser::getId,Multifile::getCreator)
                .eq(Multifile::getObjId,ywPatrolTaskRecord.getId())
                .eq(Multifile::getIsdeleted,Constants.ZERO)
                .eq(Multifile::getObjType,Constants.MultiFile.FN_PATROL_TASK_RECORD_FILE.getKey()));
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(multifileList)){
            String path = systemDictDataBiz.queryByCode(Constants.FTP,Constants.FTP_RESOURCE_PATH).getCode()
                    +systemDictDataBiz.queryByCode(Constants.FTP,Constants.YW_PATROL).getCode();
            for (Multifile multifile:multifileList) {
                if(StringUtils.isNotBlank(multifile.getFileurl())){
                    multifile.setFileurlFull(path + multifile.getFileurl());
                }
            }
            ywPatrolTaskRecord.setMultifileList(multifileList);
        }
        return ywPatrolTaskRecord;
    }
    @Override
    public YwPatrolTaskRecord getDetail(Integer id) {
        YwPatrolTaskRecord ywPatrolTaskRecord = ywPatrolTaskRecordMapper.selectJoinOne(YwPatrolTaskRecord.class,new MPJLambdaWrapper<YwPatrolTaskRecord>()
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/YwPatrolTaskServiceImpl.java
@@ -87,7 +87,7 @@
                .selectAs(YwPatrolScheme::getTitle,YwPatrolTask::getPlanTitle)
                .selectAs(SystemUser::getRealname,YwPatrolTask::getUserName)
                .select(" ( select count(1) from yw_patrol_task_record ytr where ytr.TASK_ID = t.id  and t.ISDELETED = 0  ) ",YwPatrolTask::getPatrolNum)
                .select(" ( select count(1) from yw_patrol_task_record ytr where ytr.TASK_ID = t.id  and t.STATUS = 1 and t.ISDELETED = 0) ",YwPatrolTask::getPatrolNum)
                .select(" ( select count(1) from yw_patrol_task_record ytr where ytr.TASK_ID = t.id  and t.STATUS = 1 and t.ISDELETED = 0) ",YwPatrolTask::getFinishNum)
                .leftJoin(SystemUser.class,SystemUser::getId,YwPatrolTask::getDealUserId)
                .leftJoin(YwPatrolScheme.class,YwPatrolScheme::getId,YwPatrolTask::getSchemeId)
                .eq(YwPatrolTask::getIsdeleted, Constants.ZERO)
@@ -141,12 +141,12 @@
                .selectAs(YwPatrolScheme::getTitle,YwPatrolTask::getPlanTitle)
                .selectAs(SystemUser::getRealname,YwPatrolTask::getUserName)
                .select(" ( select count(1) from yw_patrol_task_record ytr where ytr.TASK_ID = t.id  and t.ISDELETED = 0  ) ",YwPatrolTask::getPatrolNum)
                .select(" ( select count(1) from yw_patrol_task_record ytr where ytr.TASK_ID = t.id  and t.STATUS = 1 and t.ISDELETED = 0) ",YwPatrolTask::getPatrolNum)
                .select(" ( select count(1) from yw_patrol_task_record ytr where ytr.TASK_ID = t.id  and t.STATUS = 1 and t.ISDELETED = 0) ",YwPatrolTask::getFinishNum)
                .leftJoin(SystemUser.class,SystemUser::getId,YwPatrolTask::getDealUserId)
                .leftJoin(YwPatrolScheme.class,YwPatrolScheme::getId,YwPatrolTask::getSchemeId)
                .eq(YwPatrolTask::getIsdeleted, Constants.ZERO)
                .eq(Objects.nonNull(model.getStatus()) && !Constants.equalsInteger(model.getStatus(),Constants.TWO),YwPatrolTask::getStatus, model.getStatus())
                .eq(Objects.nonNull(model.getDealUserId()),YwPatrolTask::getDealUserId, model.getDealUserId())
                .eq(Objects.nonNull(model.getDealUserId()),YwPatrolScheme::getUserIds, model.getDealUserId())
                .apply(Objects.nonNull(model.getStatus()) && Constants.equalsInteger(model.getStatus(),Constants.TWO)," t.status = 1 and t.END_DATE > now() ")
                .apply(StringUtils.isNotBlank(model.getQueryStatus())," find_in_set(t.status ,'"+model.getQueryStatus()+"') ")
                .like(StringUtils.isNotBlank(model.getPlanTitle()),YwPatrolScheme::getTitle,model.getPlanTitle())
server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/hksync/HkSyncVisitServiceImpl.java
@@ -294,7 +294,7 @@
            return   ;
        }
        Constants.DEALING_HK_VISIT =true;
        String path = systemDictDataBiz.queryByCode(Constants.FTP,Constants.FTP_RESOURCE_PATH).getCode()
        String path = systemDictDataBiz.queryByCode(Constants.FTP,Constants.FTP_LOCAL_RESOURCE_PATH).getCode()
                +systemDictDataBiz.queryByCode(Constants.FTP,Constants.MEMBER_IMG).getCode();
        List<DeviceRole> roleList = deviceRoleMapper.selectList(new QueryWrapper<DeviceRole>().lambda()
                .eq(DeviceRole::getType, Constants.ONE));
server/visits/dmvisit_service/src/main/resources/application-pro.yml
@@ -1,9 +1,9 @@
spring:
  # 数据源配置
  datasource:
    url: jdbc:mysql://localhost:3306/funingyunwei?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: funing@2024
    url: jdbc:mysql://rm-bp136n33jr035pbfl3o.mysql.rds.aliyuncs.com:3306/funingyunwei?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: zhcg
    password: Fnwtzx@1127$dmtt
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
  redis: