jiangping
2024-11-27 57552bf3ffb83ba2e1096d374f11be6133db1615
Merge remote-tracking branch 'origin/master'
已添加23个文件
已修改27个文件
3813 ■■■■■ 文件已修改
admin/src/api/Inspection/ywPatrolLine.js 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/Inspection/ywPatrolScheme.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/Inspection/ywPatrolTask.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/company.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/member.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/business/ywAccount.js 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/project/ywProject.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/system/common.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/components/common/QueryForm/queryForm.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/Inspection/components/OperaYwPatrolLineWindow.vue 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/Inspection/components/OperaYwPatrolPointWindow.vue 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/Inspection/components/OperaYwPatrolSchemeWindow.vue 196 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/Inspection/components/taskDetail.vue 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/Inspection/path.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/Inspection/plan.vue 83 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/Inspection/task.vue 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/client/components/staffEdit.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/client/staffList.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/finance/account.vue 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/finance/company.vue 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/finance/components/accountEdit.vue 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/finance/components/companyEdit.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/operation/components/deviceEdit.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/operation/components/maintain.vue 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/operation/components/maintainDetail.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/operation/record.vue 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/project/components/OperaYwProjectWindow.vue 73 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/project/projectList.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/views/workorder/components/detail.vue 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/.gitignore 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/App.vue 250 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/api/index.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/api/staff.js 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/index.html 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/main.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/manifest.json 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages.json 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/pages/index/index.vue 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/static/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
h5/store/index.js 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/uni.promisify.adaptor.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/uni.scss 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/utils/config.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/utils/http.api.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/utils/http.interceptor.js 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/utils/login.js 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/utils/meetingHttp.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/utils/qrcode.js 1201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/utils/service.js 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5/utils/utils.js 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
admin/src/api/Inspection/ywPatrolLine.js
@@ -24,7 +24,10 @@
export function updateById (data) {
  return request.post('/visitsAdmin/cloudService/business/ywPatrolLine/updateById', data)
}
// è¯¦æƒ…
export function detailById (id) {
  return request.get(`/visitsAdmin/cloudService/business/ywPatrolLine/${id}`)
}
// åˆ é™¤
export function deleteById (id) {
  return request.get(`/visitsAdmin/cloudService/business/ywPatrolLine/delete/${id}`)
admin/src/api/Inspection/ywPatrolScheme.js
@@ -24,11 +24,19 @@
export function updateById (data) {
  return request.post('/visitsAdmin/cloudService/business/ywPatrolScheme/updateById', data)
}
// ä¿®æ”¹
export function updateStatusById (data) {
  return request.post('/visitsAdmin/cloudService/business/ywPatrolScheme/updateStatus', data)
}
// åˆ é™¤
export function deleteById (id) {
  return request.get(`/visitsAdmin/cloudService/business/ywPatrolScheme/delete/${id}`)
}
// åˆ é™¤
export function detailById (id) {
  return request.get(`/visitsAdmin/cloudService/business/ywPatrolScheme/${id}`)
}
// æ‰¹é‡åˆ é™¤
export function deleteByIdInBatch (ids) {
admin/src/api/Inspection/ywPatrolTask.js
@@ -29,6 +29,9 @@
export function deleteById (id) {
  return request.get(`/visitsAdmin/cloudService/business/ywPatrolTask/delete/${id}`)
}
export function getDetail (data) {
  return request.post(`/visitsAdmin/cloudService/business/ywPatrolTaskRecord/page`, data)
}
// æ‰¹é‡åˆ é™¤
export function deleteByIdInBatch (ids) {
admin/src/api/business/company.js
@@ -24,6 +24,13 @@
export function create (data) {
  return request.post('/visitsAdmin/cloudService/business/company/create', data)
}
// åˆ›å»ºè´¢åŠ¡å…¬å¸
export function createFinanceCompany (data) {
  return request.post('/visitsAdmin/cloudService/business/company/createFinanceCompany', data)
}
export function updateFinanceCompany (data) {
  return request.post('/visitsAdmin/cloudService/business/company/updateFinanceCompany', data)
}
// ä¿®æ”¹
export function updateById (data) {
@@ -50,6 +57,9 @@
export function deleteById (id) {
  return request.get(`/visitsAdmin/cloudService/business/company/delete/${id}`)
}
export function updateStatusById (data) {
  return request.post('/visitsAdmin/cloudService/business/company/updateStatusById', data)
}
// æ ¹æ®ç±»åž‹æŸ¥è¯¢ç»„织信息
export function findCompanyTreePage (type) {
admin/src/api/business/member.js
@@ -46,6 +46,10 @@
export function updateById (data) {
  return request.post('/visitsAdmin/cloudService/business/member/updateById', data)
}
export function updateStatusById (data) {
  return request.post('/visitsAdmin/cloudService/business/member/updateStatusById', data)
}
export function updateHead (data) {
  return request.post('/visitsAdmin/cloudService/business/member/updateHead', data)
}
admin/src/api/business/ywAccount.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
import request from '../../utils/request'
// æŸ¥è¯¢
export function fetchList (data) {
  return request.post('/visitsAdmin/cloudService/business/ywAccount/page', data)
}
// åˆ›å»º
export function create (data) {
  return request.post('/visitsAdmin/cloudService/business/ywAccount/create', data)
}
// åˆ›å»ºè´¢åŠ¡å…¬å¸
export function createFinanceywAccount (data) {
  return request.post('/visitsAdmin/cloudService/business/ywAccount/createFinanceywAccount', data)
}
export function updateFinanceywAccount (data) {
  return request.post('/visitsAdmin/cloudService/business/ywAccount/updateFinanceywAccount', data)
}
// ä¿®æ”¹
export function updateById (data) {
  return request.post('/visitsAdmin/cloudService/business/ywAccount/updateById', data)
}
export function sort (data) {
  return request.post('/visitsAdmin/cloudService/business/ywAccount/updateSort', data)
}
// éƒ¨é—¨ä¿¡æ¯åŒæ­¥
export function ywAccountSync (data) {
  return request.post('/visitsAdmin/cloudService/business/ywAccount/syncAll', data)
}
// åˆ†é¡µæŸ¥è¯¢
export function ywAccountGetList (data) {
  return request.post('/visitsAdmin/cloudService/business/ywAccount/page', data)
}
// æŸ¥è¯¢æ‰€æœ‰éƒ¨é—¨
export function ywAccountGetListPost (data) {
  return request.post('/visitsAdmin/cloudService/business/ywAccount/list', data)
}
// åˆ é™¤
export function deleteById (id) {
  return request.get(`/visitsAdmin/cloudService/business/ywAccount/delete/${id}`)
}
export function detailById (id) {
  return request.get(`/visitsAdmin/cloudService/business/ywAccount/${id}`)
}
export function updateStatusById (data) {
  return request.post('/visitsAdmin/cloudService/business/ywAccount/updateStatusById', data)
}
// æ ¹æ®ç±»åž‹æŸ¥è¯¢ç»„织信息
export function findywAccountTreePage (type) {
  return request.get(`/visitsAdmin/cloudService/business/ywAccount/findywAccountTreePage?type=${type}`)
}
// æ‰¹é‡åˆ é™¤
export function deleteByIdInBatch (ids) {
  return request.get('/visitsAdmin/cloudService/business/ywAccount/delete/batch', {
    params: {
      ids
    }
  })
}
admin/src/api/project/ywProject.js
@@ -34,6 +34,10 @@
export function deleteById (id) {
  return request.get(`/visitsAdmin/cloudService/business/ywProject/delete/${id}`)
}
// åˆ é™¤
export function detailById (id) {
  return request.get(`/visitsAdmin/cloudService/business/ywProject/${id}`)
}
// æ‰¹é‡åˆ é™¤
export function deleteByIdInBatch (ids) {
admin/src/api/system/common.js
@@ -71,3 +71,7 @@
export function upload (data) {
  return request.post('/visitsAdmin/cloudService/public/upload', data)
}
// èŽ·å–çœå¸‚åŒºæ ‘
export function getCityTree (data) {
  return request.post('/visitsAdmin/cloudService/business/areas/treeList', data)
}
admin/src/components/common/QueryForm/queryForm.vue
@@ -58,8 +58,8 @@
      </template>
      <!-- æ“ä½œ -->
      <el-form-item>
        <el-button type="primary" @click="handleQuery">搜索</el-button>
        <el-button v-if="showQk" @click="clear">重置</el-button>
        <el-button style="width: 56px" type="primary" @click="handleQuery">搜索</el-button>
        <el-button style="width: 56px" v-if="showQk" @click="clear">重置</el-button>
        <slot name="btns" />
        <template v-if="queryFormConfig.formItems.length > listLength">
          <el-button v-if="!showZk" type="text" @click="zkBtn">展开<i
admin/src/views/Inspection/components/OperaYwPatrolLineWindow.vue
@@ -48,7 +48,7 @@
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import { getFetchList } from '@/api/Inspection/ywPatrolPoint'
import { create } from '@/api/Inspection/ywPatrolLine'
import { create,detailById } from '@/api/Inspection/ywPatrolLine'
import { Message } from 'element-ui'
export default {
  name: 'OperaYwPatrolLineWindow',
@@ -82,13 +82,21 @@
      if (list.length == 0) return Message.warning('请先选择巡检点')
      form.linePointList = list
      create({ ...form }).then(res => {
        if (res.code == 200) {
          Message.success('保存成功')
          this.close()
        }
        Message.success('保存成功')
        this.$emit('success')
        this.close()
      })
    },
    getDetail(row) {
      detailById(row.id).then(res => {
        this.form = res
        this.list = res.linePointList || []
      })
    },
    initData() {
      this.list = []
      getFetchList({}).then(res => {
        this.pointList = res || []
      })
@@ -130,13 +138,12 @@
          needScancode: '1',
          pointName: i.name,
          pointId: i.id,
          code: i.code,
          id: i.id
          code: i.code
        })
      })
      this.isShowModal = false
    },
    close(){
    close() {
      this.visible = false
      this.$emit('success')
    }
admin/src/views/Inspection/components/OperaYwPatrolPointWindow.vue
@@ -30,7 +30,7 @@
        <el-input type="textarea" :rows="4" v-model="form.content" placeholder="请输入" />
      </el-form-item>
      <el-form-item label="上传图片" prop="imgurl">
        <UploadAvatarImage :file="{ 'imgurlfull': form.imgurlfull, 'imgurl': form.imgurl }"
        <UploadAvatarImage :file="{ 'imgurlfull': form.fileFullUrl, 'imgurl': form.fileurl }"
          :uploadData="{ folder: 'ywPatrol/' }" @uploadSuccess="uploadAvatarSuccess" @uploadEnd="isUploading = false"
          @uploadBegin="isUploading = true" />
      </el-form-item>
@@ -45,6 +45,7 @@
import mapDrag from '@/components/common/map/mapDrag.vue'
import { fetchList } from '@/api/business/category'
import { detail } from '@/api/Inspection/ywPatrolPoint'
import { fetchList as getDeiceList } from '@/api/Inspection/device'
export default {
  name: 'OperaYwPatrolPointWindow',
  extends: BaseOpera,
@@ -81,50 +82,57 @@
    open(title, row) {
      this.title = title
      this.visible = true
      this.initData()
      if (row && row.id) {
        this.getDetail(row)
      }
    },
    getDetail(row) {
      detail(row.id).then(res => {
        this.form = { ...res }
        this.form = { ...res }
        // this.$set(this.form, 'areaId', res.areaId)
        // console.log('res', res)
        // console.log('res', this.form)
        this.initData(res.areaId)
      })
    },
    initData(areaId) {
    initData() {
      fetchList({
        model: { type: 4 },
        capacity: 1000,
        page: 1,
      }).then(res => {
        this.cateList = res.records || []
        console.log('this.form.areaId', this.form)
        if (areaId) {
          this.cateList.forEach(item => {
            if (item.childCategoryList) {
              item.childCategoryList.forEach(item2 => {
                if (item2.id == areaId) {
                  this.$set(this.form, 'areaIds', [item.id, item2.id])
                  console.log('areaIds', this.form)
                }
              })
            }
          })
        }
        setTimeout(() => {
          const areaId = this.form.areaId
          if (areaId) {
            this.cateList.forEach(item => {
              if (item.childCategoryList) {
                item.childCategoryList.forEach(item2 => {
                  if (item2.id == areaId) {
                    this.$set(this.form, 'areaIds', [item.id, item2.id])
                  }
                })
              }
            })
          }
        }, 1300)
      })
      getDeiceList({
        model: {},
        capacity: 1000,
        page: 1,
      }).then(res => {
        this.deviceList = res.records
      })
    },
    getCenter(data) {
      // console.log(data)
      // this.$set(this.form, 'postion', data.address)
      if(data.lng){
      if (data.lng) {
        this.$set(this.form, 'lnglat', data.lng + ',' + data.lat)
      }else{
      } else {
        this.$set(this.form, 'lnglat', '')
      }
      this.$set(this.form, 'longitude', data.lng)
@@ -138,8 +146,8 @@
      }
    },
    uploadAvatarSuccess(file) {
      this.form.imgurl = file.imgurl
      this.form.imgurlfull = file.imgurlfull
      this.form.fileurl = file.imgurl
      this.form.fileFullUrl = file.imgurlfull
    },
  }
}
admin/src/views/Inspection/components/OperaYwPatrolSchemeWindow.vue
@@ -1,38 +1,52 @@
<template>
  <GlobalWindow width="520px" :title="title" :visible.sync="visible" :confirm-working="isWorking" @confirm="confirm">
  <GlobalWindow width="520px" :title="title" @close="close" :visible.sync="visible" :confirm-working="isWorking"
    @confirm="confirm">
    <div class="warnning">
      {{ form.id ? '编辑计划对已生成的任务无效,会在下次生成任务时生效,且当天不会生成两个任务' : '新建巡检计划会从当天开始,按照配置规则产生对应的巡检任务' }}
    </div>
    <el-form :model="form" ref="form" :rules="rules">
      <el-form-item label="计划名称" prop="title">
        <el-input v-model="form.title" placeholder="请输入标题" v-trim />
      </el-form-item>
      <el-form-item label="巡检线路">
        <el-select v-model="form.status" filterable clearable>
          <el-option value="0" label="每天"></el-option>
          <el-option value="1" label="每周"></el-option>
          <el-option value="2" label="每月"></el-option>
      <el-form-item label="巡检线路" prop="lineId">
        <el-select v-model="form.lineId" filterable clearable>
          <el-option v-for="item in lineList" :value="item.id" :label="item.name"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="巡检负责人">
      <el-form-item label="巡检负责人" prop="userIds">
        <el-select v-model="form.userIds" filterable clearable>
          <el-option value="0" label="每天"></el-option>
          <el-option value="1" label="每周"></el-option>
          <el-option value="2" label="每月"></el-option>
          <el-option v-for="item in staffList" :value="item.id" :label="item.realname"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="计划开始日期-结束日期">
        <el-date-picker v-model="form.selDate" is-range range-separator="-" value-format="yyyy-MM-dd" type="daterange"
          start-placeholder="开始日期" end-placeholder="结束日期" class="w400" />
      <el-form-item label="计划开始日期-结束日期" prop="selDate">
        <el-date-picker v-model="form.selDate" @change="changeDate" is-range range-separator="-"
          value-format="yyyy-MM-dd" type="daterange" start-placeholder="开始日期" end-placeholder="结束日期" />
      </el-form-item>
      <el-form-item label="计划执行时间">
        <el-time-picker v-model="form.selTime" is-range range-separator="-" format="HH:mm" value-format="HH:mm:ss"
          start-placeholder="开始时间" end-placeholder="结束时间" placeholder="选择时间范围" class="w400" />
        <el-time-picker v-model="form.selTime" @change="changeTime" is-range range-separator="-" format="HH:mm"
          value-format="HH:mm:ss" start-placeholder="开始时间" end-placeholder="结束时间" placeholder="选择时间范围" />
      </el-form-item>
      <el-form-item label="循环周期">
        <el-select v-model="form.circleType" filterable clearable>
          <el-option value="0" label="每天"></el-option>
          <el-option value="1" label="每周"></el-option>
          <el-option value="2" label="每月"></el-option>
      <el-form-item label="重复频率">
        <el-select v-model="form.circleType" @change="changeType" filterable>
          <el-option :value="0" label="每天"></el-option>
          <el-option :value="1" label="每周"></el-option>
          <el-option :value="2" label="每月"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item v-if="form.circleType == 1" prop="circleDays" label="重复规则">
        <div class="weeks">
          <div class="week" @click="weekClick(i)" :class="{ active: item.sel }" v-for="item, i in weeks">{{ item.la }}
          </div>
        </div>
      </el-form-item>
      <el-form-item v-if="form.circleType == 2" prop="circleDays" label="重复规则">
        <div class="weeks">
          <div class="week" @click="monthClick(i)" :class="{ active: item.sel }" v-for="item, i in monthsList">{{
            item.la
            }}</div>
        </div>
      </el-form-item>
    </el-form>
  </GlobalWindow>
</template>
@@ -40,6 +54,9 @@
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import { fetchList as getLineList } from '@/api/Inspection/ywPatrolLine'
import { detailById } from '@/api/Inspection/ywPatrolScheme'
import { getUserList } from '@/api/system/user'
export default {
  name: 'OperaYwPatrolSchemeWindow',
  extends: BaseOpera,
@@ -63,7 +80,7 @@
        dealUserId: '',
        dealDate: '',
        dealInfo: '',
        circleType: '',
        circleType: 0,
        circleDays: '',
        startDate: '',
        endDate: '',
@@ -71,10 +88,26 @@
        endTime: '',
        processStatus: '',
        selDate: [],
        selTime: [],
      },
      // éªŒè¯è§„则
      lineList: [],
      staffList: [],
      weeks: [
        { la: '周一', va: 1, sel: false },
        { la: '周二', va: 2, sel: false },
        { la: '周三', va: 3, sel: false },
        { la: '周四', va: 4, sel: false },
        { la: '周五', va: 5, sel: false },
        { la: '周六', va: 6, sel: false },
        { la: '周日', va: 7, sel: false },
      ],
      monthsList: [],
      selCircleDays: [],
      rules: {
        title: [{ required: true, message: '请输入' }],
        lineId: [{ required: true, message: '请选择' }],
        userIds: [{ required: true, message: '请选择' }],
        selDate: [{ type: 'array', required: true, message: '请选择' }],
        circleDays: [{ required: true, message: '请选择' }],
      }
    }
  },
@@ -85,10 +118,125 @@
    })
  },
  methods: {
    weekClick(i) {
      this.weeks.forEach((item, index) => {
        if (i == index) { item.sel = !item.sel }
      })
      this.$set(this.form, 'circleDays', this.weeks.filter(j => j.sel).map(a => a.va).join(','))
    },
    monthClick(i) {
      this.monthsList.forEach((item, index) => {
        if (i == index) { item.sel = !item.sel }
      })
      this.$set(this.form, 'circleDays', this.monthsList.filter(j => j.sel).map(a => a.va).join(','))
    },
    changeTime(e) {
      if (e && e.length > 0) {
        this.$set(this.form, 'startTime', e[0])
        this.$set(this.form, 'endTime', e[1])
      } else {
        this.$set(this.form, 'startTime', '')
        this.$set(this.form, 'endTime', '')
      }
    },
    changeDate(e) {
      if (e && e.length > 0) {
        this.$set(this.form, 'startDate', e[0])
        this.$set(this.form, 'endDate', e[1])
      } else {
        this.$set(this.form, 'startDate', '')
        this.$set(this.form, 'endDate', '')
      }
    },
    changeType() {
      this.$set(this.form, 'circleDays', '')
    },
    getDetail(id) {
      detailById(id).then(res => {
        this.form = res
        if (res.userIds) {
          this.$set(this.form, 'userIds', Number(res.userIds))
        }
        if (res.startTime) {
          this.$set(this.form, 'selTime', [res.startTime, res.endTime])
        }
        if (res.circleDays) {
          const circleDays = res.circleDays.split(',')
          if (res.circleType == 1) {
            circleDays.forEach(i => {
              this.weeks.forEach(j => {
                if (i == j.va) {
                  j.sel = true
                }
              })
            })
          } else {
            setTimeout(() => {
              circleDays.forEach(i => {
                this.monthsList.forEach(j => {
                  if (i == j.va) {
                    j.sel = true
                  }
                })
              })
            }, 500)
          }
        }
        this.$set(this.form, 'selDate', [res.startDate, res.endDate])
      })
    },
    initData() {
      getLineList({
        model: {},
        capacity: 9999,
        page: 1,
      }).then(res => {
        this.lineList = res.records
      })
      getUserList({}).then(res => {
        this.staffList = res
      })
      this.monthsList = []
      for (let i = 1; i < 32; i++) {
        this.monthsList.push({ la: i, va: i, sel: false })
      }
    },
    close() {
      this.$refs.form.resetFields()
      this.visible = false
    }
  }
}
</script>
<style lang="scss" scoped>
@import '@/assets/style/variables.scss';
.warnning{
  padding: 6px 10px;
  background-color: #fcf3e6;
  font-size: 12px;
  color: #333333;
}
.weeks {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  .week {
    border: 1px solid #999999;
    width: 40px;
    height: 18px;
    text-align: center;
    line-height: 18px;
    font-size: 12px;
    margin-right: 8px;
    cursor: pointer;
    margin-bottom: 6px;
  }
  .active {
    color: $primary-color;
    border: 1px solid $primary-color;
  }
}
</style>
admin/src/views/Inspection/components/taskDetail.vue
@@ -2,16 +2,22 @@
  <GlobalWindow title="巡检任务详情" :showConfirm="false" :visible.sync="isShowModal">
    <QueryForm v-model="filters" :query-form-config="queryFormConfig" @handleQuery="getList(1)" @clear="clear" />
    <el-table v-loading="loading" :data="list" stripe>
      <el-table-column prop="" label="巡检点名称" min-width="100" show-overflow-tooltip />
      <el-table-column prop="" label="状态" min-width="100" show-overflow-tooltip />
      <el-table-column prop="" label="巡检人" min-width="100" show-overflow-tooltip />
      <el-table-column prop="" label="巡检时间" min-width="100" show-overflow-tooltip />
      <el-table-column prop="" label="巡检结果" min-width="100" show-overflow-tooltip />
      <el-table-column prop="" label="巡检说明" min-width="100" show-overflow-tooltip>
        <template v-slot="scope">
          <span>{{ scope.row.billCode || scope.row.contractNum }}</span>
      <el-table-column prop="pointName" label="巡检点名称" min-width="100" show-overflow-tooltip />
      <el-table-column prop="" label="状态" min-width="100" show-overflow-tooltip>
        <template v-slot="{ row }">
          <span v-if="row.status == 0">待开始</span>
          <span v-if="row.status == 1">已巡检</span>
        </template>
      </el-table-column>
      <el-table-column prop="editor" label="巡检人" min-width="100" show-overflow-tooltip />
      <el-table-column prop="editDate" label="巡检时间" min-width="100" show-overflow-tooltip />
      <el-table-column prop="" label="巡检结果" min-width="100" show-overflow-tooltip>
        <template v-slot="{ row }">
          <span class="gray" v-if="row.dealStatus == 0">正常</span>
          <span class="red" v-if="row.dealStatus == 1">异常</span>
        </template>
      </el-table-column>
      <el-table-column prop="dealInfo" label="巡检说明" min-width="100" show-overflow-tooltip />
    </el-table>
    <div class="mt20">
      <Pagination @size-change="handleSizeChange" @current-change="getDetail" :pagination="pagination" />
@@ -23,11 +29,12 @@
import GlobalWindow from '@/components/common/GlobalWindow'
import QueryForm from '@/components/common/QueryForm'
import Pagination from '@/components/common/Pagination'
import { getDetail } from '@/api/Inspection/ywPatrolTask'
export default {
  components: { GlobalWindow, QueryForm, Pagination },
  data() {
    return {
      isShowModal: true,
      isShowModal: false,
      id: '',
      pagination: {
        pageSize: 10,
@@ -40,16 +47,19 @@
      queryFormConfig: {
        formItems: [
          {
            filed: 'name',
            filed: 'pointName',
            type: 'input',
            label: '巡检点名称'
          },
          {
            filed: 'status',
            type: 'select',
            label: '执行状态',
            label: '状态',
            placeholder: '全部',
            options: []
            options: [
              { label: '待开始', value: 0 },
              { label: '已巡检', value: 1 },
            ]
          },
        ],
        online: true
@@ -60,10 +70,10 @@
    getDetail(page) {
      const { pagination, filters, id } = this
      this.loading = true
      platformLogPage({
      getDetail({
        model: {
          ...filters,
          id,
          taskId: id,
        },
        sorts: [{ direction: 'DESC', property: 'param1' }],
        capacity: pagination.pageSize,
@@ -71,6 +81,7 @@
      }).then(res => {
        this.loading = false
        this.list = res.records || []
        this.pagination.total = res.total
        this.list.forEach(item => {
          item.inTypeTemp = item.inType == 0 ? '整托盘' : '件烟'
          item.taskOrigin = 'WMS获取'
@@ -94,5 +105,3 @@
  }
}
</script>
<style lang="scss" scoped></style>
admin/src/views/Inspection/path.vue
@@ -91,6 +91,7 @@
    editClick(row) {
      if (row && row.id) {
        this.$refs.operaYwPatrolLineWindow.open('编辑巡检线路')
        this.$refs.operaYwPatrolLineWindow.getDetail(row)
      } else {
        this.$refs.operaYwPatrolLineWindow.open('新建巡检线路')
      }
admin/src/views/Inspection/plan.vue
@@ -2,16 +2,12 @@
  <TableLayout :permissions="['business:ywpatrolscheme:query']">
    <!-- æœç´¢è¡¨å• -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
      <el-form-item label="标题" prop="title">
      <el-form-item label="计划标题" prop="title">
        <el-input v-model="searchForm.title" placeholder="请输入标题" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="开始日期" prop="startDate">
        <el-date-picker v-model="searchForm.startDate" value-format="yyyy-MM-dd" placeholder="请输入开始日期"
          @change="search" />
      </el-form-item>
      <el-form-item label="结束日期" prop="endDate">
        <el-date-picker v-model="searchForm.endDate" value-format="yyyy-MM-dd" placeholder="请输入结束日期" @change="search" />
      <el-form-item label="计划日期" prop="selDate">
        <el-date-picker type="daterange" v-model="searchForm.selDate" clearable value-format="yyyy-MM-dd"
          @change="changeDate" />
      </el-form-item>
      <section>
@@ -24,7 +20,7 @@
    <!-- è¡¨æ ¼å’Œåˆ†é¡µ -->
    <template v-slot:table-wrap>
      <ul class="toolbar" v-permissions="['business:ywpatrolscheme:create', 'business:ywpatrolscheme:delete']">
        <li><el-button type="primary" @click="$refs.operaYwPatrolSchemeWindow.open('新建巡检计划')" icon="el-icon-plus"
        <li><el-button type="primary" @click="editClick()" icon="el-icon-plus"
            v-permissions="['business:ywpatrolscheme:create']">新建</el-button></li>
        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete"
            v-permissions="['business:ywpatrolscheme:delete']">删除</el-button></li>
@@ -34,30 +30,36 @@
        <el-table-column prop="title" label="计划名称" min-width="100px"></el-table-column>
        <el-table-column prop="lineId" label="计划编号" min-width="100px"></el-table-column>
        <el-table-column prop="dealDate" label="负责人员" min-width="100px"></el-table-column>
        <el-table-column prop="userName" label="负责人员" min-width="100px"></el-table-column>
        <el-table-column prop="startDate" label="计划日期" min-width="100px">
        <el-table-column prop="startDate" label="计划日期" min-width="150px">
          <template v-slot="scope">
            <span>{{ scope.row.startDate }} - {{ scope.row.endDate }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="startDate" label="执行时间" min-width="100px">
        <el-table-column prop="startDate" label="执行时间" min-width="130px">
          <template v-slot="scope">
            <span>{{ scope.row.startTime }} - {{ scope.row.endTime }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="" label="创建人" min-width="100px"></el-table-column>
        <el-table-column prop="" label="执行结果" min-width="100px"></el-table-column>
        <el-table-column prop="createUserName" label="创建人" min-width="100px"></el-table-column>
        <el-table-column prop="" label="执行结果" min-width="100px">
          <template v-slot="scope">
            <span v-if="scope.row.schemeStatus == 0">待开始</span>
            <span v-if="scope.row.schemeStatus == 1">进行中</span>
            <span v-if="scope.row.schemeStatus == 2">已结束</span>
          </template>
        </el-table-column>
        <el-table-column label="状态" min-width="100px">
          <template v-slot="scope">
            <el-switch v-model="scope.row.status" @change="changeStatus" active-value="0" inactive-value="1">
            <el-switch v-model="scope.row.status" @change="e => changeStatus(scope.row)" :active-value="0" :inactive-value="1">
            </el-switch>
          </template>
        </el-table-column>
        <el-table-column v-if="containPermissions(['business:ywpatrolscheme:update', 'business:ywpatrolscheme:delete'])"
          label="操作" min-width="120" fixed="right">
          <template slot-scope="{row}">
            <el-button type="text" @click="$refs.operaYwPatrolSchemeWindow.open('编辑巡检计划', row)" icon="el-icon-edit"
            <el-button type="text" @click="editClick(row)" icon="el-icon-edit"
              v-permissions="['business:ywpatrolscheme:update']">编辑</el-button>
            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete"
              v-permissions="['business:ywpatrolscheme:delete']">删除</el-button>
@@ -77,6 +79,8 @@
import TableLayout from '@/layouts/TableLayout'
import Pagination from '@/components/common/Pagination'
import OperaYwPatrolSchemeWindow from './components/OperaYwPatrolSchemeWindow'
import { updateStatusById } from '@/api/Inspection/ywPatrolScheme'
import { Message } from 'element-ui'
export default {
  name: 'YwPatrolScheme',
  extends: BaseTable,
@@ -85,28 +89,7 @@
    return {
      // æœç´¢
      searchForm: {
        id: '',
        creator: '',
        createDate: '',
        editor: '',
        editDate: '',
        isdeleted: '',
        title: '',
        remark: '',
        status: '',
        sortnum: '',
        lineId: '',
        userIds: '',
        dealUserId: '',
        dealDate: '',
        dealInfo: '',
        circleType: '',
        circleDays: '',
        startDate: '',
        endDate: '',
        startTime: '',
        endTime: '',
        processStatus: ''
       title: ''
      }
    }
  },
@@ -120,9 +103,33 @@
    this.search()
  },
  methods: {
    changeStatus(e) {
      console.log(e);
      updateStatusById(e).then(res => {
        this.search()
        Message.success('状态修改成功')
      }, () => {
        this.search()
      })
    },
    changeDate(e) {
      if(e && e.length > 0){
        this.$set(this.searchForm, 'startDate', e[0])
        this.$set(this.searchForm, 'endDate', e[1])
      }else{
        this.$set(this.searchForm, 'startDate', '')
        this.$set(this.searchForm, 'endDate', '')
      }
    },
    reset() {
      this.searchForm = {}
      this.search()
    },
    editClick(row) {
      if (row && row.id) {
        this.$refs.operaYwPatrolSchemeWindow.open('编辑巡检计划')
        this.$refs.operaYwPatrolSchemeWindow.getDetail(row.id)
      } else {
        this.$refs.operaYwPatrolSchemeWindow.open('新建巡检计划')
      }
admin/src/views/Inspection/task.vue
@@ -2,11 +2,11 @@
  <TableLayout :permissions="['business:ywpatroltask:query']">
    <!-- æœç´¢è¡¨å• -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
      <el-form-item label="计划名称" prop="title">
        <el-input v-model="searchForm.title" placeholder="请输入计划名称" @keypress.enter.native="search"></el-input>
      <el-form-item label="计划名称" prop="planTitle">
        <el-input v-model="searchForm.planTitle" placeholder="请输入计划名称" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item >
        <el-select v-model="searchForm.status" filterable clearable>
      <el-form-item label="任务状态">
        <el-select v-model="searchForm.status" label="任务状态" filterable clearable>
          <el-option value="0" label="待开始"></el-option>
          <el-option value="1" label="进行中"></el-option>
          <el-option value="2" label="已超期"></el-option>
@@ -30,11 +30,11 @@
      >
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column prop="planTitle" label="计划名称" min-width="100px"></el-table-column>
        <el-table-column prop="schemeId" label="计划编号" min-width="100px"></el-table-column>
        <el-table-column prop="planCode" label="计划编号" min-width="100px"></el-table-column>
        <el-table-column prop="code" label="任务编号" min-width="100px"></el-table-column>
        <el-table-column prop="dealDate" label="任务时间" min-width="100px">
        <el-table-column prop="dealDate" label="任务时间" min-width="140px">
          <template v-slot="scope">
            <span>{{ scope.row.startDate }} {{ scope.row.endDate }}</span>
            <span v-if="scope.row.startDate && scope.row.endDate">{{ scope.row.startDate.slice(0, 16) }} - {{ scope.row.endDate.slice(11, 16) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="dealDate" label="实际完成时间" min-width="100px"></el-table-column>
@@ -55,7 +55,8 @@
          fixed="right"
        >
          <template slot-scope="{row}">
            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:ywpatroltask:delete']">取消</el-button>
            <el-button type="text" @click="handleDetail(row)">查看详情</el-button>
            <el-button type="text" @click="cancelById(row)" v-permissions="['business:ywpatroltask:delete']">取消</el-button>
          </template>
        </el-table-column>
      </el-table>
@@ -104,6 +105,9 @@
      this.$refs.TaskDetailRef.id = row.id
      this.$refs.TaskDetailRef.getDetail()
    },
    cancelById() {
    },
  }
}
</script>
admin/src/views/client/components/staffEdit.vue
@@ -1,6 +1,6 @@
<template>
  <GlobalWindow :title="title" width="900px" :visible.sync="visible" :confirm-working="isWorking" @confirm="confirm">
    <el-form :model="form" ref="form" :rules="rules">
  <GlobalWindow :title="title" width="820px" :visible.sync="visible" :confirm-working="isWorking" @confirm="confirm">
    <el-form :model="form" ref="form" label-position="top" :rules="rules">
      <div class="list">
        <el-form-item label="客户名称" prop="customerId">
          <el-select v-model="form.customerId" clearable filterable>
admin/src/views/client/staffList.vue
@@ -37,8 +37,12 @@
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" min-width="100px">
          <template slot-scope="{row}">
            <span :class="{ red: row.status == 1 }">{{ row.status == '0' ? '正常' : '禁用' }}</span>
            <el-switch v-model="row.status" @change="e => changeStatus(row)" :active-value="0"
              :inactive-value="1">
            </el-switch>
            <!-- <span :class="{ red: row.status == 1 }">{{ row.status == '0' ? '正常' : '禁用' }}</span> -->
          </template>
        </el-table-column>
        <el-table-column v-if="containPermissions(['business:ywcustomer:update', 'business:ywcustomer:delete'])"
@@ -65,6 +69,8 @@
import Pagination from '@/components/common/Pagination'
import OperaYwCustomerWindow from './components/staffEdit.vue'
import { fetchList } from '@/api/client/ywCustomer'
import { updateStatusById } from '@/api/business/member'
import { Message } from 'element-ui'
export default {
  name: 'YwCustomer',
  extends: BaseTable,
@@ -90,6 +96,14 @@
    this.initData()
  },
  methods: {
    changeStatus(e) {
      updateStatusById(e).then(res => {
        this.search()
        Message.success('状态修改成功')
      }, () => {
        this.search()
      })
    },
    initData() {
      fetchList({
        capacity: 9000,
admin/src/views/finance/account.vue
@@ -6,15 +6,20 @@
        v-permissions="['business:ywpatrolline:create']">新建</el-button>
    </div>
    <el-table v-loading="loading" :data="list" stripe>
      <el-table-column prop="code" label="收支条目" min-width="100" show-overflow-tooltip />
      <el-table-column prop="name" label="收款公司" min-width="100" show-overflow-tooltip />
      <el-table-column prop="" label="账户类型" min-width="100" show-overflow-tooltip />
      <el-table-column prop="modelNo" label="账户名称" min-width="100" show-overflow-tooltip />
      <el-table-column prop="realName" label="开户银行" min-width="100" show-overflow-tooltip />
      <el-table-column prop="realName" label="银行账号" min-width="100" show-overflow-tooltip />
      <el-table-column prop="title" label="收支条目" min-width="100" show-overflow-tooltip />
      <el-table-column prop="companyName" label="收款公司" min-width="100" show-overflow-tooltip />
      <el-table-column label="账户类型" min-width="100" show-overflow-tooltip>
        <template v-slot="{row}">
          <span v-if="row.type == 0">对公</span>
          <span v-if="row.type == 1">个人</span>
        </template>
      </el-table-column>
      <el-table-column prop="name" label="账户名称" min-width="100" show-overflow-tooltip />
      <el-table-column prop="bankName" label="开户银行" min-width="100" show-overflow-tooltip />
      <el-table-column prop="bankNo" label="银行账号" min-width="100" show-overflow-tooltip />
      <el-table-column prop="status" label="状态" min-width="100" show-overflow-tooltip>
        <template v-slot="scope">
          <el-switch v-model="scope.row.status" active-value="0" inactive-value="1">
          <el-switch v-model="scope.row.status" @change="e =>changeStatus(scope.row)" :active-value="0" :inactive-value="1">
          </el-switch>
        </template>
      </el-table-column>
@@ -22,7 +27,7 @@
        <template slot-scope="{row}">
          <el-button type="text" @click="handleEdit(row)" icon="el-icon-edit"
            v-permissions="['business:category:update']">编辑</el-button>
          <el-button type="text" @click="deleteById(row)" icon="el-icon-delete"
          <el-button type="text" @click="handleDel(row)" icon="el-icon-delete"
            v-permissions="['business:category:delete']">删除</el-button>
        </template>
      </el-table-column>
@@ -38,7 +43,9 @@
import Pagination from '@/components/common/Pagination'
import QueryForm from '@/components/common/QueryForm'
import Edit from './components/accountEdit.vue'
import { companyGetList, deleteById } from '@/api/business/company'
import { fetchList, updateById, deleteById } from '@/api/business/ywAccount'
import { companyGetList } from '@/api/business/company'
import { Message } from 'element-ui'
export default {
  components: {
    Pagination,
@@ -60,14 +67,17 @@
      queryFormConfig: {
        formItems: [
          {
            filed: 'name',
            filed: 'title',
            type: 'input',
            label: '收支条目'
          },
          {
            filed: 'name',
            filed: 'companyId',
            type: 'select',
            label: '收款公司'
            label: '收款公司',
            labelCode: 'name',
            valueCode: 'id',
            options: []
          },
        ],
        online: true
@@ -76,15 +86,15 @@
  },
  created() {
    this.getList()
    this.getCompany()
  },
  methods: {
    getList(page) {
      const { pagination, filters } = this
      this.loading = true
      companyGetList({
      fetchList({
        model: {
          ...filters,
          type: 2
        },
        capacity: pagination.pageSize,
        page: page || pagination.page,
@@ -99,6 +109,23 @@
        this.loading = false
      })
    },
    changeStatus(row) {
      updateById(row).then(res => {
        this.getList()
        Message.success('更新状态成功')
      }, () => {
        this.getList()
      })
    },
    getCompany(){
      companyGetList({
        model: {type: 2},
        capacity: 9999,
        page: 1
      }).then(res => {
       this.queryFormConfig.formItems[1].options = res.records || []
      })
    },
    handleEdit(row) {
      this.showEdit = true
      this.$nextTick(() => {
@@ -110,10 +137,9 @@
    },
    handleDel(row) {
      let message = `确认删除该记录吗?`
      let message = `确认删除该账户吗?`
      this.$dialog.deleteConfirm(message)
        .then(() => {
          this.isWorking.delete = true
          deleteById(row.id)
            .then(() => {
              this.$tip.apiSuccess('删除成功')
admin/src/views/finance/company.vue
@@ -6,14 +6,14 @@
        v-permissions="['business:ywpatrolline:create']">新建</el-button>
    </div>
    <el-table v-loading="loading" :data="list" stripe>
      <el-table-column prop="code" label="公司名称" min-width="100" show-overflow-tooltip />
      <el-table-column prop="name" label="公司简介" min-width="100" show-overflow-tooltip />
      <el-table-column prop="" label="纳税识别号" min-width="100" show-overflow-tooltip />
      <el-table-column prop="modelNo" label="公司地址" min-width="100" show-overflow-tooltip />
      <el-table-column prop="realName" label="收支账户数量" min-width="100" show-overflow-tooltip />
      <el-table-column prop="name" label="公司名称" min-width="100" show-overflow-tooltip />
      <el-table-column prop="shortName" label="公司简介" min-width="100" show-overflow-tooltip />
      <el-table-column prop="code" label="纳税识别号" min-width="100" show-overflow-tooltip />
      <el-table-column prop="address" label="公司地址" min-width="100" show-overflow-tooltip />
      <el-table-column prop="accountNum" label="收支账户数量" min-width="100" show-overflow-tooltip />
      <el-table-column prop="status" label="状态" min-width="100" show-overflow-tooltip>
        <template v-slot="scope">
          <el-switch v-model="scope.row.status" active-value="0" inactive-value="1">
          <el-switch v-model="scope.row.status" @change="e => changeStatus(scope.row)" :active-value="0" :inactive-value="1">
          </el-switch>
        </template>
      </el-table-column>
@@ -21,7 +21,7 @@
        <template slot-scope="{row}">
          <el-button type="text" @click="handleEdit(row)" icon="el-icon-edit"
            v-permissions="['business:category:update']">编辑</el-button>
          <el-button type="text" @click="deleteById(row)" icon="el-icon-delete"
          <el-button type="text" @click="handleDel(row)" icon="el-icon-delete"
            v-permissions="['business:category:delete']">删除</el-button>
        </template>
      </el-table-column>
@@ -37,7 +37,8 @@
import Pagination from '@/components/common/Pagination'
import QueryForm from '@/components/common/QueryForm'
import Edit from './components/companyEdit.vue'
import { companyGetList, deleteById } from '@/api/business/company'
import { companyGetList, deleteById, updateStatusById } from '@/api/business/company'
import { Message } from 'element-ui'
export default {
  components: {
    Pagination,
@@ -72,6 +73,14 @@
    this.getList()
  },
  methods: {
    changeStatus(row) {
      updateStatusById(row).then(res => {
        this.getList()
        Message.success('更新状态成功')
      }, () => {
        this.getList()
      })
    },
    getList(page) {
      const { pagination, filters } = this
      this.loading = true
@@ -104,10 +113,9 @@
    },
    handleDel(row) {
      let message = `确认删除该记录吗?`
      let message = `确认删除该公司吗?`
      this.$dialog.deleteConfirm(message)
        .then(() => {
          this.isWorking.delete = true
          deleteById(row.id)
            .then(() => {
              this.$tip.apiSuccess('删除成功')
admin/src/views/finance/components/accountEdit.vue
@@ -1,32 +1,32 @@
<template>
  <GlobalWindow :title="param.id ? '编辑公司' : '新建公司'" :confirmWorking="subLoading" :visible.sync="isShowModal"
  <GlobalWindow :title="param.id ? '编辑账户' : '新建账户'" :confirmWorking="subLoading" :visible.sync="isShowModal"
    width="600px" @close="close" @confirm="handleSub">
    <el-form :model="param" ref="paramRef" :rules="rules">
      <el-form-item label="收支条目" prop="name">
        <el-input v-model="param.name" placeholder="请输入" v-trim />
      <el-form-item label="收支条目" prop="title">
        <el-input v-model="param.title" placeholder="请输入" v-trim />
      </el-form-item>
      <el-form-item label="收款公司" prop="name">
        <el-select v-model="param.realName" filterable clearable>
          <el-option value="0" label="xxx"></el-option>
      <el-form-item label="收款公司" prop="companyId">
        <el-select v-model="param.companyId" filterable clearable>
          <el-option v-for="item in comList" :value="item.id" :label="item.name"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="收款类型" prop="name">
        <el-radio-group v-model="param.radio">
      <el-form-item label="收款类型" prop="type">
        <el-radio-group v-model="param.type">
          <el-radio :label="0">对公</el-radio>
          <el-radio :label="1">个人</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="账户名称" prop="desc">
        <el-input v-model="param.desc" placeholder="请输入" v-trim />
      <el-form-item label="账户名称" prop="name">
        <el-input v-model="param.name" placeholder="请输入" v-trim />
      </el-form-item>
      <el-form-item label="开户名称">
        <el-input v-model="param.code" placeholder="请输入" v-trim />
      <el-form-item label="开户银行" prop="bankName">
        <el-input v-model="param.bankName" placeholder="请输入" v-trim />
      </el-form-item>
      <el-form-item label="银行账号">
        <el-input v-model="param.addr" placeholder="请输入" v-trim />
      <el-form-item label="银行账号" prop="bankNo">
        <el-input v-model="param.bankNo" placeholder="请输入" v-trim />
      </el-form-item>
      <el-form-item label="状态" prop="code">
        <el-switch v-model="param.status" active-value="0" inactive-value="1">
      <el-form-item label="状态" prop="status">
        <el-switch v-model="param.status" :active-value="0" :inactive-value="1">
        </el-switch>
      </el-form-item>
    </el-form>
@@ -36,7 +36,8 @@
<script>
import GlobalWindow from '@/components/common/GlobalWindow'
import UploadAvatarImage from '@/components/common/UploadAvatarImage'
import { create, updateById } from '@/api/business/company'
import { create, updateById, detailById } from '@/api/business/ywAccount'
import {  companyGetList } from '@/api/business/company'
import { Message } from 'element-ui'
export default {
  components: { GlobalWindow, UploadAvatarImage },
@@ -45,18 +46,23 @@
      isShowModal: false,
      subLoading: false,
      param: {
        type: 2,
        status: '0'
        type: 0,
        status: 0
      },
      cateList: [],
      comList: [],
      rules: {
        name: [{ required: true, message: '请输入' }],
        desc: [{ required: true, message: '请输入' }]
        title: [{ required: true, message: '请输入' }],
        bankName: [{ required: true, message: '请输入' }],
        bankNo: [{ required: true, message: '请输入' }],
        status: [{ required: true, message: '请选择' }],
        type: [{ required: true, message: '请选择' }],
        companyId: [{ required: true, message: '请选择' }],
      },
    }
  },
  created() {
    this.getCompany()
  },
  methods: {
    handleSub() {
@@ -76,6 +82,21 @@
        }
      })
    },
    getDetail(id) {
      detailById(id).then(res => {
        this.param = res
      })
    },
    getCompany(){
      companyGetList({
        model: {type: 2},
        capacity: 9999,
        page: 1
      }).then(res => {
       this.comList = res.records || []
      })
    },
    changeSel(e) {
      if (e && e.length == 1) {
        this.$set(this.param, 'catePId', e[0])
admin/src/views/finance/components/companyEdit.vue
@@ -5,14 +5,14 @@
      <el-form-item label="公司名称" prop="name">
        <el-input v-model="param.name" placeholder="请输入" v-trim />
      </el-form-item>
      <el-form-item label="公司简介" prop="desc">
        <el-input v-model="param.desc" placeholder="请输入" v-trim />
      <el-form-item label="公司简介" prop="shortName">
        <el-input v-model="param.shortName" placeholder="请输入" v-trim />
      </el-form-item>
      <el-form-item label="纳税识别号">
        <el-input v-model="param.code" placeholder="请输入" v-trim />
      </el-form-item>
      <el-form-item label="联系地址">
        <el-input v-model="param.addr" placeholder="请输入" v-trim />
        <el-input v-model="param.address" placeholder="请输入" v-trim />
      </el-form-item>
      <el-form-item label="状态" prop="code">
        <el-switch v-model="param.status" active-value="0" inactive-value="1">
@@ -25,7 +25,7 @@
<script>
import GlobalWindow from '@/components/common/GlobalWindow'
import UploadAvatarImage from '@/components/common/UploadAvatarImage'
import { create, updateById } from '@/api/business/company'
import { createFinanceCompany, updateFinanceCompany } from '@/api/business/company'
import { Message } from 'element-ui'
export default {
  components: { GlobalWindow, UploadAvatarImage },
@@ -52,7 +52,7 @@
      const { param, subLoading } = this
      this.$refs['paramRef'].validate((valid) => {
        if (valid) {
          let fn = param.id ? updateById : create
          let fn = param.id ? updateFinanceCompany : createFinanceCompany
          this.subLoading = true
          fn(param).then(res => {
            this.subLoading = false
admin/src/views/operation/components/deviceEdit.vue
@@ -43,7 +43,7 @@
        </el-select>
      </el-form-item>
      <el-form-item label="照片" prop="">
        <UploadAvatarImage :file="{ 'imgurlfull': param.imgurlfull, 'imgurl': param.imgurl }"
        <UploadAvatarImage :file="{ 'imgurlfull': param.fileFullUrl, 'imgurl': param.fileUrl }"
          :uploadData="{ folder: 'ywDevice/' }" @uploadSuccess="uploadAvatarSuccess" @uploadEnd="isUploading = false"
          @uploadBegin="isUploading = true" />
      </el-form-item>
@@ -109,7 +109,6 @@
                  if (item2.id == cateId) {
                    this.$set(this.param, 'cateIds', [item.id, item2.id])
                    console.log('cateId', this.form)
                  }
                })
              }
@@ -141,8 +140,8 @@
      }
    },
    uploadAvatarSuccess(file) {
      this.$set(this.param, 'imgurl', file.imgurl)
      this.$set(this.param, 'imgurlfull', file.imgurlfull)
      this.$set(this.param, 'fileUrl', file.imgurl)
      this.$set(this.param, 'fileFullUrl', file.imgurlfull)
    },
    close() {
      this.isShowModal = false
admin/src/views/operation/components/maintain.vue
@@ -2,21 +2,21 @@
  <GlobalWindow :title="param.id ? '编辑运维记录' : '新建运维记录'" :confirmWorking="subLoading" :visible.sync="isShowModal"
    width="600px" @close="close" @confirm="handleSub">
    <el-form :model="param" ref="paramRef" :rules="rules">
      <el-form-item label="选择设备" prop="code">
      <el-form-item label="选择设备" prop="deviceId">
        <el-select v-model="param.deviceId" filterable clearable>
          <el-option v-for="item in deviceList" :value="item" :label="item"></el-option>
          <el-option v-for="item in deviceList" :value="item.id" :label="item.name"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="运维人员" prop="code">
        <el-select v-model="param.realName" filterable clearable>
          <el-option v-for="item in 10" :value="item" :label="item"></el-option>
      <el-form-item label="运维人员" prop="userId">
        <el-select v-model="param.userId" filterable clearable>
          <el-option v-for="item in staffList" :value="item.id" :label="item.realname"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="设备状态" prop="">
        <el-select v-model="param.status" filterable clearable>
          <el-option value="0" label="正常"></el-option>
          <el-option value="1" label="损坏"></el-option>
          <el-option value="2" label="报废"></el-option>
          <el-option :value="0" label="正常"></el-option>
          <el-option :value="1" label="损坏"></el-option>
          <el-option :value="2" label="报废"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="现场照片" prop="">
@@ -37,17 +37,13 @@
          </div>
        </div>
      </el-form-item>
      <el-form-item label="运维备注" prop="">
        <el-input type="textarea" :rows="4" v-model="param.remark" placeholder="请输入" />
      <el-form-item label="运维备注" prop="content">
        <el-input type="textarea" :rows="4" v-model="param.content" placeholder="请输入" />
      </el-form-item>
      <el-form-item label="运维时间" prop="">
      <el-form-item label="运维时间" prop="dealDate">
        <el-date-picker v-model="param.dealDate" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
          type="datetime"></el-date-picker>
      </el-form-item>
    </el-form>
  </GlobalWindow>
</template>
@@ -56,6 +52,8 @@
import GlobalWindow from '@/components/common/GlobalWindow'
import UploadAvatarImage from '@/components/common/UploadAvatarImage'
import { fetchList } from '@/api/Inspection/device'
import { getUserList } from '@/api/system/user'
import { create, updateById } from '@/api/Inspection/deviceRecord'
import { Message, Loading } from 'element-ui'
export default {
  components: { GlobalWindow, UploadAvatarImage },
@@ -65,9 +63,11 @@
      subLoading: false,
      param: {},
      deviceList: [],
      staffList: [],
      rules: {
        name: [{ required: true, message: '请输入' }],
        code: [{ required: true, message: '请输入' }]
        deviceId: [{ required: true, message: '请选择' }],
        content: [{ required: true, message: '请输入' }],
        // code: [{ required: true, message: '请输入' }],
      },
      loadingInstance: null,
@@ -84,18 +84,19 @@
  },
  methods: {
    handleSub() {
      const { param, subLoading } = this
      const { param, subLoading, fileList } = this
      this.$refs['paramRef'].validate((valid) => {
        if (valid) {
          let fn = param.id ? updateById : create
          if(fileList && fileList.length > 0){
            param.multifileList = fileList
          }
          this.subLoading = true
          fn(param).then(res => {
            if (res.code == 200) {
              this.subLoading = false
            this.subLoading = false
              this.$emit('success')
              Message.success('保存成功')
              this.close()
            }
          }).catch(() => {
            this.subLoading = false
          })
@@ -108,9 +109,11 @@
        capacity: 1000,
        page: 1,
      }).then(res => {
        this.deviceList = res || []
        this.deviceList = res.records
      })
      getUserList({}).then(res => {
        this.staffList = res
      })
    },
    changeSel(e) {
      if (e && e.length == 1) {
@@ -155,12 +158,14 @@
      if (['.mp4', '.avi', '.flv', '.wmv'].some(char => item.imgaddr.includes(char))) {
        this.fileList.push({
          type: 1,
          objType: 6,
          fileurl: item.imgaddr,
          fileurlFull: item.url
        })
      } else {
        this.fileList.push({
          type: 0,
          objType: 6,
          fileurl: item.imgaddr,
          fileurlFull: item.url
        })
@@ -184,7 +189,8 @@
.file_list {
  display: flex;
  flex-wrap: wrap;
  .avatar-uploader{
  .avatar-uploader {
    width: 92px;
    height: 92px;
    display: flex;
@@ -192,6 +198,7 @@
    align-items: center;
    border: 1px dashed #d9d9d9;
  }
  .item {
    width: 92px;
    max-height: 92px;
admin/src/views/operation/components/maintainDetail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,104 @@
<template>
  <GlobalWindow title="设备运维详情" :showConfirm="false" :visible.sync="visible" width="800px">
    <div class="model_wrap">
      <div class="list">
        <div class="item">
          <div class="la">设备名称</div>
          <div class="val">{{ info.deviceName }}</div>
        </div>
        <div class="item">
          <div class="la">设备编号</div>
          <div class="val">{{ info.deviceCode }}</div>
        </div>
        <div class="item">
          <div class="la">设备状态</div>
          <div class="val" v-if="info.status == 0">正常</div>
          <div class="val" v-if="info.status == 1">损坏</div>
          <div class="val" v-if="info.status == 2">报废</div>
        </div>
        <div class="item">
          <div class="la">运维人</div>
          <div class="val">{{ info.realName }}</div>
        </div>
        <div class="item">
          <div class="la">运维人电话</div>
          <div class="val">{{ info.mobile }}</div>
        </div>
        <div class="item">
          <div class="la">运维时间</div>
          <div class="val">{{ info.dealDate }}</div>
        </div>
        <div class="item max">
          <div class="la">运维备注</div>
          <div class="val">{{ info.content }}</div>
        </div>
        <div class="item max">
          <div class="la">现场照片</div>
          <div class="value" v-if="info.multifileList == null || !info.multifileList.length">无</div>
          <div class="value" v-if="info.multifileList != null && info.multifileList.length">
            <div v-for="item in info.multifileList" :key="item.id" style="display: inline;margin-right: 20px">
              <video v-if="item.fileurlFull && item.fileurlFull.endsWith('.mp4')" ref="videoRef" controls preload="auto"
                style="width: 80px;height: 80px;object-fit: contain;" :src="item.fileurlFull" />
              <el-image v-else-if="item.fileurlFull" style="width:80px; height: 80px" :src="item.fileurlFull"
                :preview-src-list="[item.fileurlFull]">
              </el-image>
            </div>
          </div>
        </div>
      </div>
    </div>
  </GlobalWindow>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import { detailById } from '@/api/Inspection/deviceRecord'
export default {
  extends: BaseOpera,
  components: { GlobalWindow },
  data() {
    return {
      // è¡¨å•数据
      info: {},
    }
  },
  created() {
  },
  methods: {
    getDetail(id) {
      detailById(id).then(res => {
        this.info = res
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.model_wrap {
  padding-top: 20px;
  .title {
    font-size: 18px;
    font-weight: 600;
    margin-bottom: 16px;
  }
  .list {
    display: flex;
    flex-wrap: wrap;
    .item {
      width: 33.33%;
      margin-bottom: 8px;
      .la {
        color: #7f7f7f
      }
    }
    .max{
      width: 100%;
    }
  }
}
</style>
admin/src/views/operation/record.vue
@@ -7,16 +7,21 @@
      <el-button type="primary" @click="handleEx" v-permissions="['business:ywpatrolline:create']">导出</el-button>
    </div>
    <el-table v-loading="loading" :data="list" stripe>
      <el-table-column prop="" label="运维人" min-width="100" show-overflow-tooltip />
      <el-table-column prop="code" label="设备编号" min-width="100" show-overflow-tooltip />
      <el-table-column prop="name" label="设备名称" min-width="100" show-overflow-tooltip />
      <el-table-column prop="stautsName" label="设备状态" min-width="100" show-overflow-tooltip />
      <el-table-column prop="remark" label="运维备注" min-width="100" show-overflow-tooltip />
      <el-table-column prop="createTime" label="创建时间" min-width="100" show-overflow-tooltip />
      <el-table-column prop="realName" label="运维人" min-width="100" show-overflow-tooltip />
      <el-table-column prop="deviceCode" label="设备编号" min-width="100" show-overflow-tooltip />
      <el-table-column prop="deviceName" label="设备名称" min-width="100" show-overflow-tooltip />
      <el-table-column prop="status" label="设备状态" min-width="100" show-overflow-tooltip>
        <template slot-scope="{row}">
          <span v-if="row.status == 0">正常</span>
          <span v-if="row.status == 1">损坏</span>
          <span v-if="row.status == 2">报废</span>
        </template>
      </el-table-column>
      <el-table-column prop="content" label="运维备注" min-width="100" show-overflow-tooltip />
      <el-table-column prop="createDate" label="创建时间" min-width="140" show-overflow-tooltip />
      <el-table-column label="操作" min-width="120" fixed="right">
        <template slot-scope="{row}">
          <el-button type="text" @click="handleDetail(row)" icon="el-icon-edit"
            v-permissions="['business:category:update']">查看</el-button>
          <el-button type="text" @click="handleDetail(row)" v-permissions="['business:category:update']">查看</el-button>
        </template>
      </el-table-column>
    </el-table>
@@ -24,6 +29,7 @@
      <Pagination @size-change="handleSizeChange" @current-change="getList" :pagination="pagination" />
    </div>
    <Edit v-if="showEdit" ref="EditRef" @success="getList" @close="showEdit = false" />
    <Detail ref="DetailRef" />
  </div>
</template>
@@ -31,12 +37,14 @@
import Pagination from '@/components/common/Pagination'
import QueryForm from '@/components/common/QueryForm'
import Edit from './components/maintain.vue'
import { fetchList, deleteById } from '@/api/Inspection/device'
import Detail from './components/maintainDetail.vue'
import { fetchList, deleteById } from '@/api/Inspection/deviceRecord'
export default {
  components: {
    Pagination,
    QueryForm,
    Edit
    Edit,
    Detail
  },
  data() {
    return {
@@ -105,8 +113,9 @@
      })
    },
    handleDetail() {
    handleDetail(row) {
      this.$refs.DetailRef.visible = true
      this.$refs.DetailRef.getDetail(row.id)
    },
    handleDel(row) {
      let message = `确认删除该记录吗?`
admin/src/views/project/components/OperaYwProjectWindow.vue
@@ -1,23 +1,22 @@
<template>
  <GlobalWindow
    :title="title"
    :visible.sync="visible"
    :confirm-working="isWorking"
    @confirm="confirm"
  >
  <GlobalWindow :title="title" :visible.sync="visible" :confirm-working="isWorking" @confirm="confirm">
    <el-form :model="form" ref="form" :rules="rules">
      <el-form-item label="项目名称" prop="name">
        <el-input v-model="form.name" placeholder="请输入名称" v-trim/>
        <el-input v-model="form.name" placeholder="请输入名称" v-trim />
      </el-form-item>
      <el-form-item label="所属地址" prop="addr">
        <el-input v-model="form.addr" placeholder="请输入详细地址"/>
      <el-form-item label="所属地区" prop="addr">
        <el-cascader v-model="form.areaIdT" :props="{
          label: 'name',
          value: 'id',
          children: 'childList'
        }" :options="treeList" @change="handleChange"></el-cascader>
      </el-form-item>
      <el-form-item label="详细地址" prop="addr">
        <el-input v-model="form.addr" placeholder="请输入详细地址"/>
        <el-input v-model="form.addr" placeholder="请输入详细地址" />
      </el-form-item>
      <el-form-item label="项目简介" prop="remark">
        <el-input type="textarea" :rows="4" v-model="form.remark" placeholder="请输入"/>
        <el-input type="textarea" :rows="4" v-model="form.remark" placeholder="请输入" />
      </el-form-item>
    </el-form>
  </GlobalWindow>
@@ -26,11 +25,13 @@
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import { getCityTree } from '@/api/system/common'
import { detailById } from '@/api/project/ywProject'
export default {
  name: 'OperaYwProjectWindow',
  extends: BaseOpera,
  components: { GlobalWindow },
  data () {
  data() {
    return {
      // è¡¨å•数据
      form: {
@@ -45,23 +46,65 @@
        status: '',
        sortnum: '',
        imgurl: '',
        areaIdT: '',
        cityId: '',
        areaId: '',
        provinceId: '',
        addr: ''
      },
      // éªŒè¯è§„则
      rules: {
        name: [{ required: true, message: '请输入项目名称', trigger: 'blur' }]
      },
      projectList: []
      projectList: [],
      treeList: []
    }
  },
  created () {
  created() {
    this.config({
      api: '/project/ywProject',
      'field.id': 'id'
    })
  },
  methods: {
    open(title, target) {
      this.title = title
      this.visible = true
      this.initData()
      this.$nextTick(() => {
        for (const key in this.form) {
          this.form[key] = target[key]
        }
        this.$set(this.form, 'areaIdT', [target.provinceId, target.cityId, target.areaId,])
        // console.log(this.form)
      })
    },
    handleChange(e) {
      if (e && e.length > 0) {
        if (e.length == 3) {
          this.$set(this.form, 'areaId', e[2])
        } else if (e.length == 2) {
          this.$set(this.form, 'areaId', e[1])
        } else {
          this.$set(this.form, 'areaId', e[0])
        }
      }
    },
    getDetail(id) {
      detailById(id).then(res => {
        this.form = res
      })
    },
    initData() {
      getCityTree({
        "type": 0
      }).then(res => {
        this.treeList = res
      })
    }
  }
}
</script>
admin/src/views/project/projectList.vue
@@ -15,7 +15,7 @@
    <!-- è¡¨æ ¼å’Œåˆ†é¡µ -->
    <template v-slot:table-wrap>
      <ul class="toolbar" v-permissions="['business:ywproject:create', 'business:ywproject:delete']">
        <li><el-button type="primary" @click="$refs.operaYwProjectWindow.open('新建项目')" icon="el-icon-plus" v-permissions="['business:ywproject:create']">新建</el-button></li>
        <li><el-button type="primary" @click="handleEdit()" icon="el-icon-plus" v-permissions="['business:ywproject:create']">新建</el-button></li>
        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:ywproject:delete']">删除</el-button></li>
      </ul>
      <el-table
@@ -36,7 +36,7 @@
          fixed="right"
        >
          <template slot-scope="{row}">
            <el-button type="text" @click="$refs.operaYwProjectWindow.open('编辑项目', row)" icon="el-icon-edit" v-permissions="['business:ywproject:update']">编辑</el-button>
            <el-button type="text" @click="handleEdit(row)" icon="el-icon-edit" v-permissions="['business:ywproject:update']">编辑</el-button>
            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:ywproject:delete']">删除</el-button>
          </template>
        </el-table-column>
@@ -90,6 +90,16 @@
      'field.main': 'id'
    })
    this.search()
  },
  methods: {
    handleEdit(row){
      if(row && row.id){
        this.$refs.operaYwProjectWindow.open('编辑项目', row)
      }else{
        this.$refs.operaYwProjectWindow.open('新建项目')
        // this.$refs.operaYwProjectWindow.open('新建项目')
      }
    }
  }
}
</script>
admin/src/views/workorder/components/detail.vue
@@ -1,5 +1,5 @@
<template>
  <GlobalWindow width="820px" title="工单详情" :visible.sync="visible" :confirm-working="isWorking" @close="close"
  <GlobalWindow width="900px" title="工单详情" :visible.sync="visible" :confirm-working="isWorking" @close="close"
    @confirm="confirm">
    <div class="main">
      <div class="title">
@@ -10,50 +10,68 @@
          <div class="status gray" v-if="info.dealStatus == 2">已处理</div>
        </div>
      </div>
      <div class="list">
        <div class="item">
          <div class="la">位置类型</div>
          <div class="val">{{ info.areaType == 0 ? '室内维修' : '公共维修' }}</div>
        </div>
        <div class="item">
          <div class="la">对应位置</div>
          <div class="val">{{ info.buildingName }} / {{ info.roomNum || info.floorName }}</div>
        </div>
        <div class="item">
          <div class="la">工单类别</div>
          <div class="val">{{ info.categoryName }}</div>
        </div>
        <div class="item">
          <div class="la">上报人</div>
          <div class="val">{{ info.creatorName }}</div>
        </div>
        <div class="item">
          <div class="la">上报人电话</div>
          <div class="val">{{ info.creatorPhone }}</div>
        </div>
        <div class="item">
          <div class="la">上报时间</div>
          <div class="val">{{ info.createDate }}</div>
        </div>
        <div class="item max">
          <div class="la">上门时间</div>
          <div class="val">{{ info.getDate }}</div>
        </div>
        <div class="item max">
          <div class="la">问题描述</div>
          <div class="val">{{ info.content }}</div>
        </div>
        <div class="item max">
          <div class="la">问题图片</div>
          <div class="value" v-if="info.fileList == null || !info.fileList.length">无</div>
          <div class="value" v-if="info.fileList != null && info.fileList.length">
            <div v-for="item in info.fileList" :key="item.id" style="display: inline;margin-right: 20px">
              <video v-if="item.fileurlFull && item.fileurlFull.endsWith('.mp4')" ref="videoRef" controls preload="auto"
                style="width: 80px;height: 80px;object-fit: contain;" :src="item.fileurlFull" />
              <el-image v-else-if="item.fileurlFull" style="width:80px; height: 80px" :src="item.fileurlFull"
                :preview-src-list="[item.fileurlFull]">
              </el-image>
      <div class="main_content">
        <div class="list">
          <div class="item">
            <div class="la">位置类型</div>
            <div class="val">{{ info.areaType == 0 ? '室内维修' : '公共维修' }}</div>
          </div>
          <div class="item">
            <div class="la">对应位置</div>
            <div class="val">{{ info.buildingName }} / {{ info.roomNum || info.floorName }}</div>
          </div>
          <div class="item">
            <div class="la">工单类别</div>
            <div class="val">{{ info.categoryName }}</div>
          </div>
          <div class="item">
            <div class="la">上报人</div>
            <div class="val">{{ info.creatorName }}</div>
          </div>
          <div class="item">
            <div class="la">上报人电话</div>
            <div class="val">{{ info.creatorPhone }}</div>
          </div>
          <div class="item">
            <div class="la">上报时间</div>
            <div class="val">{{ info.createDate }}</div>
          </div>
          <div class="item max">
            <div class="la">上门时间</div>
            <div class="val">{{ info.getDate }}</div>
          </div>
          <div class="item max">
            <div class="la">问题描述</div>
            <div class="val">{{ info.content }}</div>
          </div>
          <div class="item max">
            <div class="la">问题图片</div>
            <div class="value" v-if="info.fileList == null || !info.fileList.length">无</div>
            <div class="value" v-if="info.fileList != null && info.fileList.length">
              <div v-for="item in info.fileList" :key="item.id" style="display: inline;margin-right: 20px">
                <video v-if="item.fileurlFull && item.fileurlFull.endsWith('.mp4')" ref="videoRef" controls
                  preload="auto" style="width: 80px;height: 80px;object-fit: contain;" :src="item.fileurlFull" />
                <el-image v-else-if="item.fileurlFull" style="width:80px; height: 80px" :src="item.fileurlFull"
                  :preview-src-list="[item.fileurlFull]">
                </el-image>
              </div>
            </div>
          </div>
        </div>
        <div class="side">
          <div class="title">工单流转记录员</div>
          <div class="flow_list">
            <div class="item" v-for="item,i in info.logList">
              <div class="icon">
                <div class="dian"></div>
                <div v-if="i < info.logList.length - 1" class="line"></div>
              </div>
              <div class="content">
                <div class="name">{{ item.title }}</div>
                <div class="time">操作时间:{{ item.createDate }}</div>
                <div class="creator">操作人:{{ item.param1 }}</div>
              </div>
            </div>
          </div>
        </div>
      </div>
@@ -85,8 +103,8 @@
          </el-form-item>
          <el-form-item label="现场图片">
            <div class="file_list">
              <el-upload class="avatar-uploader" :data="uploadData" multiple :limit="6" :auto-upload="true" :action="uploadImgUrl"
                :show-file-list="false" :on-success="uploadAvatarSuccess" :on-error="uploadError"
              <el-upload class="avatar-uploader" :data="uploadData" multiple :limit="6" :auto-upload="true"
                :action="uploadImgUrl" :show-file-list="false" :on-success="uploadAvatarSuccess" :on-error="uploadError"
                :before-upload="beforeUpload">
                <div class="upload_wrap">
                  <i class="el-icon-plus avatar-uploader-icon"></i>
@@ -178,9 +196,9 @@
        if (valid) {
          const { param, id, dealFileList, info } = this
          let fn = null
          if(info.dealStatus == 0 || info.dealStatus == null){
          if (info.dealStatus == 0 || info.dealStatus == null) {
            fn = param.dealType == 0 ? dispatchOrder : dealOrder
          }else{
          } else {
            fn = dealOrder
          }
          fn({
@@ -326,6 +344,46 @@
      width: 100%;
    }
  }
  .main_content{
    display: flex;
    .side{
      width: 240px;
      .title{
        font-size: 14px;
      }
      .flow_list{
        .item{
          display: flex;
          .icon{
            width: 28px;
            display: flex;
            flex-direction: column;
            align-items: center;
            .dian{
              width: 12px;
              height: 12px;
              border-radius: 50%;
              background-color: #e89e42;
            }
            .line{
              width: 1px;
              height: 100%;
              background-color: #e89e42;
            }
          }
          .content{
            font-size: 12px;
            color: #999999;
            padding-bottom: 12px;
            .name{
              font-size: 13px;
              color: #333333;
            }
          }
        }
      }
    }
  }
}
.file_list {
h5/.gitignore
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
.DS_Store
coderd.json
node_modules
uni_modules
.env.development
uview-ui
/dist
/unpackage
# local env files
.env.local
.env.*.local
unpackage
admin
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
h5/App.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,250 @@
<script>
export default {
  onLaunch: function () {
  },
  onShow: function () {
    console.log('App Show')
  },
  onHide: function () {
    console.log('App Hide')
  }
}
</script>
<style lang="scss">
/*每个页面公共css */
@import "uview-ui/index.scss";
.flex-cb {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.container {
  height: 100%;
  width: 100%;
  max-width: 800rpx;
  overflow-y: auto;
}
.empty_wrap{
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    color: #666666;
    min-height: 600rpx;
    image{
        width: 300rpx;
        height: 300rpx;
    }
}
.doumee-container .ivu-tabs-nav {
  width: 100%;
}
.doumee-container .ivu-tabs-nav .ivu-tabs-tab {
  width: calc(100% / 3);
}
.doumee-container .ivu-tabs-nav .ivu-tabs-tab {
  margin-right: 0;
  text-align: center;
}
.cell {
  background-color: #fff;
  display: flex;
  justify-content: space-between;
  align-items: center;
  min-height: 100rpx;
  padding: 24rpx 30rpx;
  box-sizing: border-box;
  border-bottom: 1rpx solid #eee;
  font-size: 15rpx;
  position: relative;
}
.cell .title {
  flex-shrink: 0;
  color: #222;
  line-height: 20rpx;
  height: 20rpx;
  width: 28%;
  margin-right: 5%;
}
.cell .content {
  flex: 1;
  font-size: 28rpx;
  font-weight: 400;
  color: #999999;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
.cell .content .input {
  width: 100%;
  height: 100%;
  font-size: 28rpx;
  font-weight: 400;
  color: #333333;
  text-align: right;
}
.cell.is-link::after {
  content: "";
  display: block;
  width: 8rpx;
  height: 8rpx;
  transform: rotate(-45deg);
  border-right: 1rpx solid #999999;
  border-bottom: 1rpx solid #999999;
  margin-left: 5rpx;
}
.card {
  background-color: #fff;
  padding: 16rpx;
  position: relative;
}
.card::after {
  content: "";
  display: block;
  position: absolute;
  width: calc(100% - 32rpx);
  height: 0;
  bottom: 0;
  left: 16rpx;
  border-bottom: 1rpx solid #f7f7f7;
}
.card .title {
  color: #777777;
  margin-bottom: 12rpx;
}
.card .content {
  color: #222;
}
.placeholder9 {
  color: #999999 !important;
  font-size: 28rpx;
}
.red{
    color: red !important;
}
//设置圆角
checkbox .uni-checkbox-input {
  border-radius: 50%;
}
checkbox .uni-checkbox-input.uni-checkbox-input-checked {
  color: #fff !important;
  border: 1px solid #4d99a8 !important;
  background-color: #4d99a8 !important;
}
checkbox .uni-checkbox-input.uni-checkbox-input-checked:before {
  /* color: #4d99a8 !important;  */
  /* border: 1px solid #4d99a8 !important; */
  /* font-size: 58rpx; */
  /* border-radius: 50%; */
}
//
view {
  box-sizing: border-box;
}
image {
  box-sizing: border-box;
  margin: 0;
  display: flex;
}
input {
  font-size: 30rpx;
}
textarea {
  box-sizing: border-box;
  // background-color: #f7f7f7;
  font-size: 30rpx !important;
  padding: 0;
  border-radius: 8rpx;
  color: #333333 !important;
}
.u-textarea {
  padding: 0 !important;
  color: #333333 !important;
}
.df_ac {
  display: flex;
  align-items: center;
}
.main_app {
  padding: 0 30rpx 30rpx;
  font-size: 28rpx;
  color: #333333;
}
.popupShow {
  overflow: hidden;
  position: fixed;
  width: 100%;
}
.placeholder6 {
  color: #666666;
  font-size: 28rpx;
}
.primaryColor {
  color: $uni-color-primary;
}
.avatar {
  width: 64rpx;
  height: 64rpx;
  border-radius: 50%;
  margin-right: 20rpx;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: $uni-color-primary;
  color: #fff;
  font-size: 30rpx;
}
.placeholder9 {
  color: #999999;
  font-size: 28rpx;
}
.fs24 {
  font-size: 24rpx;
}
.mr24 {
  margin-right: 24rpx;
}
.mt24 {
  margin-top: 24rpx;
}
.mr12 {
  margin-right: 12rpx;
}
.ml12 {
  margin-left: 12rpx;
}
.ml6 {
  margin-left: 6rpx;
}
.mt6 {
  margin-top: 6rpx;
}
.mr6 {
  margin-right: 6rpx;
}
</style>
h5/api/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
import { http } from '@/utils/service.js'
export * from '@/utils/config.js'
export * from './staff'
// æŸ¥è¯¢å­—典值数据
export const getSystemDictData = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/web/other/getSystemDictData',
    data
  })
}
// æŽˆæƒ
export const wxAuthorize = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/web/visitor/wxAuthorize',
    method: 'get',
    data
  })
}
//  å‘送短信验证码
export const sendSms = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/smsEmail/sendSms',
    method: 'post',
    data
  })
}
h5/api/staff.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,232 @@
import { http } from '@/utils/service.js'
// login
export const loginPost = (data) => {
  return http({
    url: 'loginH5',
    method: 'post',
    data
  })
}
export const loginCaptcha = () => {
  return http({
    url: 'captcha',
    method: 'get'
  })
}
// åˆ·æ–°token
export const refreshToken = () => {
  return http({
    url: 'refreshtoken',
    method: 'post'
  })
}
export const getUserInfo = () => {
  return http({
    url: 'getUserInfo',
    method: 'get'
  })
}
// æŸ¥è¯¢äººå‘˜ç›¸å…³ä¿¡æ¯0劳务访客 1普通访客 2内部人员,示例值(1)
export const findTypeMemberInfo = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/member/findTypeMemberInfo',
    // url: 'visitsAdmin/cloudService/business/member/page',
    method: 'post',
    data
  })
}
//  é‡ç½®å¯†ç 
export const resetPassword = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/visits/resetPassword',
    method: 'post',
    data
  })
}
//  ä¿®æ”¹å¯†ç 
export const uploadPassword = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/member/updatePwd',
    method: 'post',
    data
  })
}
// loginout
export const logoutPost = (data) => {
  return http({
    url: '/logout',
    method: 'post',
    data
  })
}
//  é𐿂£éšæ‰‹æ‹ åˆ›å»º
export const DangerCreate = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/hiddenDanger/create',
    method: 'post',
    data
  })
}
// é𐿂£åŒºåŸŸ
export const DangerArea = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/hiddenDanger/create',
    method: 'post',
    data
  })
}
// é𐿂£ è¯¦æƒ…
export const hiddenDangerDetail = (id) => {
  return http({
    url:  `visitsAdmin/cloudService/business/hiddenDanger/${id}`,
    method: 'get'
  })
}
// éƒ¨é—¨åˆ—表
export const deptListPost = (data) => {
  return http({
    url: '/visitsAdmin/cloudService/business/company/list',
    method: 'post',
    data
  })
}
// é𐿂£ ç±»åž‹
export const DangerConfigType = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/hiddenDangerParam/list',
    method: 'post',
    data
  })
}
// é𐿂£ æŸ¥è¯¢åŒºåŸŸå†…安全员
export const findHiddenAreaMemberList = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/hiddenDangerParam/findHiddenAreaMemberList',
    method: 'post',
    data
  })
}
// é𐿂£ å¤„理
export const dealHiddenDanger = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/hiddenDanger/dealHiddenDanger',
    method: 'post',
    data
  })
}
// é𐿂£ è½¬äº¤
export const transferHiddenDanger = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/hiddenDanger/transferHiddenDanger',
    method: 'post',
    data
  })
}
// é𐿂£ æµç¨‹åˆ—表
export const findListFlowDanger = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/hiddenDangerLog/findList',
    method: 'post',
    data
  })
}
// è½¦è¾† åˆ—表
export const getCarsList = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/cars/list',
    method: 'post',
    data
  })
}
// æŸ¥è¯¢è½¦è¾†å¯é¢„约时段
export const carCanReservationDate = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/carUseBook/carCanReservationDate',
    method: 'get',
    data
  })
}
// æŸ¥è¯¢è½¦è¾† é¢„约记录
export const carUseBookList = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/carUseBook/carUseBookList',
    method: 'post',
    data
  })
}
// ç”¨è½¦ç”³è¯·æäº¤
export const carUseBookCraete = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/carUseBook/create',
    method: 'post',
    data
  })
}
// æŸ¥è¯¢è½¦è¾† æ´¾è½¦è®°å½•
export const carUseBookPaiche = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/carUseBook/page',
    method: 'post',
    data
  })
}
// æŸ¥è¯¢è½¦è¾† æ´¾è½¦è®°å½• è¯¦æƒ…
export const carUseBookDetail = (id) => {
  return http({
    url: 'visitsAdmin/cloudService/business/carUseBook/'+id,
    method: 'get'
  })
}
//  å®¡æ‰¹
export const carUseBookAppr = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/approve/approved',
    method: 'post',
    data
  })
}
// æŸ¥è¯¢è½¦è¾† æ´¾è½¦è®°å½• æ’¤é”€ç”³è¯·
export const carUseBookBack = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/carUseBook/revoke',
    method: 'get',
    data
  })
}
// æŸ¥è¯¢è½¦è¾† å¸æœºåˆ—表
export const driveListPost = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/member/driveList',
    method: 'post',
    data
  })
}
//  ä»»åŠ¡ä¸­å¿ƒ å¤´éƒ¨æ•°æ®
export const stagingHead = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/staging/taskCenterHead',
    method: 'get',
    data
  })
}
//  ä»»åŠ¡ä¸­å¿ƒ åˆ†é¡µæ•°æ®
export const stagingTaskPage = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/staging/taskPage',
    method: 'post',
    data
  })
}
//  ä»»åŠ¡ä¸­å¿ƒ æ ‡è®°å·²è¯»
export const signReadTask = (data) => {
  return http({
    url: 'visitsAdmin/cloudService/business/staging/signRead',
    method: 'get',
    data
  })
}
h5/index.html
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <script>
      var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
        CSS.supports('top: constant(a)'))
      document.write(
        '<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
        (coverSupport ? ', viewport-fit=cover' : '') + '" />')
    </script>
    <title></title>
    <!--preload-links-->
    <!--app-context-->
  </head>
  <body>
    <div id="app"><!--app-html--></div>
    <script type="module" src="/main.js"></script>
  </body>
</html>
h5/main.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
import App from './App'
import store from './store/index.js'
import uView from "uview-ui"
// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
Vue.use(uView)
Vue.prototype.$store = store
Vue.prototype.showToast = (str) => {
    setTimeout(() => {
        uni.showToast({
          title: str,
          icon: 'none',
          duration: 2000
        })
    })
}
Vue.prototype.$eventBus = new Vue()
App.mpType = 'app'
const app = new Vue({
  ...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
  const app = createSSRApp(App)
  return {
    app
  }
}
// #endif
h5/manifest.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,152 @@
{
    "name" : "laborVisitors",
    "appid" : "__UNI__BCCF400",
    "description" : "",
    "versionName" : "1.0.0",
    "versionCode" : "100",
    "transformPx" : false,
    /* 5+App特有相关 */
    "app-plus" : {
        "usingComponents" : true,
        "nvueStyleCompiler" : "uni-app",
        "compilerVersion" : 3,
        "splashscreen" : {
            "alwaysShowBeforeRender" : true,
            "waiting" : true,
            "autoclose" : true,
            "delay" : 0
        },
        /* æ¨¡å—配置 */
        "modules" : {},
        /* åº”用发布信息 */
        "distribute" : {
            /* android打包配置 */
            "android" : {
                "permissions" : [
                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                    "<uses-feature android:name=\"android.hardware.camera\"/>",
                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
                ]
            },
            /* ios打包配置 */
            "ios" : {
                "dSYMs" : false
            },
            /* SDK配置 */
            "sdkConfigs" : {
                "ad" : {}
            },
            "icons" : {
                "android" : {
                    "hdpi" : "",
                    "xhdpi" : "",
                    "xxhdpi" : "",
                    "xxxhdpi" : ""
                },
                "ios" : {
                    "appstore" : "",
                    "ipad" : {
                        "app" : "",
                        "app@2x" : "",
                        "notification" : "",
                        "notification@2x" : "",
                        "proapp@2x" : "",
                        "settings" : "",
                        "settings@2x" : "",
                        "spotlight" : "",
                        "spotlight@2x" : ""
                    },
                    "iphone" : {
                        "app@2x" : "",
                        "app@3x" : "",
                        "notification@2x" : "",
                        "notification@3x" : "",
                        "settings@2x" : "",
                        "settings@3x" : "",
                        "spotlight@2x" : "",
                        "spotlight@3x" : ""
                    }
                }
            }
        }
    },
    /* å¿«åº”用特有相关 */
    "quickapp" : {},
    /* å°ç¨‹åºç‰¹æœ‰ç›¸å…³ */
    "mp-weixin" : {
        "appid" : "wxcd2b89fd2ff065f8",
        "setting" : {
            "urlCheck" : false,
            "es6" : true,
            "postcss" : true,
            "minified" : true
        },
        "usingComponents" : true,
        "requiredPrivateInfos" : [ "getLocation", "chooseLocation" ],
        "permission" : {
            "scope.userLocation" : {
                "desc" : "用于获取周边房源位置"
            }
        }
    },
    "mp-alipay" : {
        "usingComponents" : true
    },
    "mp-baidu" : {
        "usingComponents" : true
    },
    "mp-toutiao" : {
        "usingComponents" : true
    },
    "uniStatistics" : {
        "enable" : false
    },
    "vueVersion" : "2",
    "h5" : {
        "router" : {
            "mode" : "hash",
            "base" : "./"
        },
        // "base" : "/h5/"
        "devServer" : {
            "port" : 8090,
            "historyApiFallback" : true,
            "disableHostCheck" : true,
            "proxy" : {
                "/gateway_interface" : {
                    // è¿™ä¸ªå­—段名需与你配置的basePrefixUrl一致,系统识别到带有/dev-api请求的地址时,会在前面拼接上代理服务器地址
                    // "target" : "http://172.20.10.7:10010", // ä»£ç†æœåŠ¡å™¨åŸŸåæˆ–IP地址
                    // "target" : "http://192.168.0.100:10010", // ä»£ç†æœåŠ¡å™¨åŸŸåæˆ–IP地址
                    // "target" : "http://10.50.250.253:8088/gateway_interface", // ä»£ç†æœåŠ¡å™¨åŸŸåæˆ–IP地址
                    "target" : "http://192.168.0.173/gateway_interface", // ä»£ç†æœåŠ¡å™¨åŸŸåæˆ–IP地址
                    "changeOrigin" : true, // å…è®¸è·¨åŸŸ
                    "pathRewrite" : {
                        "^/gateway_interface" : ""
                    }
                }
            },
            "https" : false
        },
        "sdkConfigs" : {
            "maps" : {
                "amap" : {
                    "key" : "d9a554b1808ce10a12a932ed9b0db1d0",
                    "securityJsCode" : "",
                    "serviceHost" : ""
                }
            }
        }
    }
}
h5/pages.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
{
    "easycom": {
        "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
    },
    "pages": [
        {
            "path": "pages/index/index",
            "style": {
                "navigationBarTitleText": "访客中心",
                "enablePullDownRefresh": false
            }
        }
    ],
    "globalStyle": {
        "navigationBarTextStyle": "black",
        "navigationBarTitleText": "",
        "navigationBarBackgroundColor": "#ffffff",
        "backgroundColor": "#ffffff"
    },
    "uniIdRouter": {}
}
h5/pages/index/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
<template>
    <view class="content">
        <image class="logo" src="/static/logo.png"></image>
        <view class="text-area">
            <text class="title">{{title}}</text>
        </view>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                title: 'Hello'
            }
        },
        onLoad() {
        },
        methods: {
        }
    }
</script>
<style>
    .content {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
    .logo {
        height: 200rpx;
        width: 200rpx;
        margin-top: 200rpx;
        margin-left: auto;
        margin-right: auto;
        margin-bottom: 50rpx;
    }
    .text-area {
        display: flex;
        justify-content: center;
    }
    .title {
        font-size: 36rpx;
        color: #8f8f94;
    }
</style>
h5/static/logo.png
h5/store/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,105 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const openId = uni.getStorageSync('openId')
const member = uni.getStorageSync('member')
// meeting
const navHeight = uni.getStorageSync('navHeight')
const statusbarHeight = uni.getStorageSync('statusbarHeight')
const height = uni.getStorageSync('height')
const token = uni.getStorageSync('token')
const time = uni.getStorageSync('time')
const userInfo = uni.getStorageSync('userInfo')
const driverInfo = uni.getStorageSync('driverInfo')
const sessionKey = uni.getStorageSync('sessionKey')
const store = new Vuex.Store({
    state: {
        // openId: openId || '061kuG0006hxcS13TT200w9VIp4kuG09',
        openId: openId || '123123',
        member: member || null,
        statusbarHeight: statusbarHeight || '0',
        navHeight: navHeight || '0',
        token: token || null,
        time: time || null,
        userInfo: userInfo || {},
        driverInfo: driverInfo || {},
        height: height || '0',
        sessionKey: sessionKey || '',
        primaryColor: '#279baa'
    },
    mutations: {
        // è®¾ç½®openId
        setOpenId(state, val) {
            state.openId = val
            uni.setStorageSync('openId', val)
        },
        // è®¾ç½®ç”¨æˆ·ä¿¡æ¯
        setMember(state, val) {
            state.member = val
            uni.setStorageSync('member', val)
        },
        // è®¾ç½®å¯¼èˆªæ é«˜åº¦
        setHeight(state, val) {
            state.navHeight = val.navHeight
            state.statusbarHeight = val.statusbarHeight
            state.height = val.height
            uni.setStorageSync('navHeight', val.navHeight)
            uni.setStorageSync('statusbarHeight', val.statusbarHeight)
            uni.setStorageSync('height', val.height)
        },
        // è®¾ç½®ç¼“å­˜token
        setToken(state, token) {
            state.token = token
            uni.setStorageSync('token', token)
        },
        // è®¾ç½®è¿‡æœŸæ—¶é—´æˆ³
        setTimeStamp(state, time) {
            state.time = time
            uni.setStorageSync('time', time)
        },
        // è®¾ç½®ç”¨æˆ·ä¿¡æ¯
        setUserInfo(state, obj) {
            state.userInfo = obj
            uni.setStorageSync('userInfo', obj)
        },
        // è®¾ç½®å¸æœºä¿¡æ¯
        setDriverInfo(state, obj) {
            state.driverInfo = obj
            uni.setStorageSync('driverInfo', obj)
        },
        // è®¾ç½®SessionKey
        setSessionKey(state, val) {
            state.sessionKey = val
            uni.setStorageSync('sessionKey', val)
        },
        // æ¸…空登录缓存
        empty(state) {
            state.token = ''
            state.userInfo = {}
            state.driverInfo = {}
            uni.removeStorageSync('userInfo')
            uni.removeStorageSync('driverInfo')
            uni.removeStorageSync('token')
        }
    },
    actions: {
        // èŽ·å–çŠ¶æ€é«˜åº¦
        getHeight(context) {
            let res = uni.getMenuButtonBoundingClientRect()
            let status = uni.getSystemInfoSync()
            var height = res.height
            let statusbarHeight = status.statusBarHeight
            let navHeight = res.height + (res.top - statusbarHeight) * 2
            context.commit('setHeight', { statusbarHeight, navHeight, height })
        }
    }
})
export default store
h5/uni.promisify.adaptor.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
uni.addInterceptor({
  returnValue (res) {
    if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
      return res;
    }
    return new Promise((resolve, reject) => {
      res.then((res) => res[0] ? reject(res[0]) : resolve(res[1]));
    });
  },
});
h5/uni.scss
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,76 @@
/**
 * è¿™é‡Œæ˜¯uni-app内置的常用样式变量
 *
 * uni-app å®˜æ–¹æ‰©å±•插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
 * å¦‚果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import è¿™ä¸ªæ–‡ä»¶ï¼‰ï¼Œæ–¹ä¾¿ç”¨æˆ·é€šè¿‡æ­ç§¯æœ¨çš„æ–¹å¼å¼€å‘整体风格一致的App
 *
 */
/**
 * å¦‚果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
 *
 * å¦‚果你的项目同样使用了scss预处理,你也可以直接在你的 scss ä»£ç ä¸­ä½¿ç”¨å¦‚下变量,同时无需 import è¿™ä¸ªæ–‡ä»¶
 */
@import 'uview-ui/theme.scss';
/* é¢œè‰²å˜é‡ */
/* è¡Œä¸ºç›¸å…³é¢œè‰² */
$uni-color-primary: #279baa;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* æ–‡å­—基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* èƒŒæ™¯é¢œè‰² */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
/* è¾¹æ¡†é¢œè‰² */
$uni-border-color:#c8c7cc;
/* å°ºå¯¸å˜é‡ */
/* æ–‡å­—尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16;
/* å›¾ç‰‡å°ºå¯¸ */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/* æ°´å¹³é—´è· */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
/* åž‚直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* é€æ˜Žåº¦ */
$uni-opacity-disabled: 0.3; // ç»„件禁用态的透明度
/* æ–‡ç« åœºæ™¯ç›¸å…³ */
$uni-color-title: #2C405A; // æ–‡ç« æ ‡é¢˜é¢œè‰²
$uni-font-size-title:20px;
$uni-color-subtitle: #555555; // äºŒçº§æ ‡é¢˜é¢œè‰²
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // æ–‡ç« æ®µè½é¢œè‰²
$uni-font-size-paragraph:15px;
h5/utils/config.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
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 uploadAvatar = `${baseUrl}visitsAdmin/cloudService/web/public/uploadFtp.do`
export const uploadUrl = `${baseUrl}visitsAdmin/cloudService/public/uploadBatch`
export const statusMap = {
    0: '待确认',
    1: '等待签到',
    2: '等待叫号', // ç­‰å¾…叫号
    3: '入园等待',
    4: '月台等待', //已叫号
    5: '作业中',
    6: '作业完成',
    7: '转移中',
    8: '异常挂起',
    9: '已授权离园',
    10: '已离园',
    11: '已过号',
}
h5/utils/http.api.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
import { baseUrl, uploadUrl } from './config'
const install = (Vue, vm) => {
    uni.$u.http.setConfig((config) => {
        config.baseURL = baseUrl
        config.timeout = 60000
        return config
    })
    Vue.prototype.$baseUrl = baseUrl
    Vue.prototype.$uploadUrl = uploadUrl
    let wxAuthorize = (params = {}) => vm.$u.http.get('visitsAdmin/cloudService/web/visitor/wxAuthorize', { params })    // è®¿å®¢å¾®ä¿¡æŽˆæƒ
    let getSystemDictData = (params = {}) => vm.$u.http.get('visitsAdmin/cloudService/web/other/getSystemDictData', { params })    // æŸ¥è¯¢å­—典值数据
    let getProblemsVO = (params = {}) => vm.$u.http.get('visitsAdmin/cloudService/web/problem/getProblemsVO', { params })    // èŽ·å–é¢˜ç›®æ•°æ®
    let finishAnswer = (data = {}) => vm.$u.http.post('visitsAdmin/cloudService/web/problem/finishAnswer', data)    // ä¿®æ”¹å½“前登录的用户信息
    let deviceRoleList = (params = {}) => vm.$u.http.get('visitsAdmin/cloudService/web/other/deviceRoleList', { params })    // è®¾å¤‡ç»„列表
    let getVisitedMember = (data = {}) => vm.$u.http.post('visitsAdmin/cloudService/web/visitor/getVisitedMember', data)    // æŸ¥è¯¢è¢«è®¿é—®äººä¿¡æ¯
    let createFk = (data = {}) => vm.$u.http.post('visitsAdmin/cloudService/web/visitor/createFk', data)    // è®¿å®¢è®°å½•提交
    let detail = (params = {}) => vm.$u.http.get('visitsAdmin/cloudService/web/visitor/detail', { params })    // è®¿å®¢è®°å½•详情
    vm.$u.api = {
        wxAuthorize,
        getSystemDictData,
        getProblemsVO,
        finishAnswer,
        deviceRoleList,
        getVisitedMember,
        createFk,
        detail
    }
}
export default { install }
h5/utils/http.interceptor.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
const install = (Vue, vm) => {
    // è¯·æ±‚拦截器
    uni.$u.http.interceptors.request.use((config) => {
        uni.showLoading({
            title: '加载中',
            mask: true
        });
        // const Headtoken = vm.$store.state.token || ''
        // if (Headtoken) {
        //     config.header['eva-auth-token'] = Headtoken;
        // }
        return config
    }, config => {
        return Promise.reject(config)
    })
    // å“åº”拦截器
    uni.$u.http.interceptors.response.use((response) => {
        uni.hideLoading();
        // ç™»å½•过期
        if (response.data.code === 401) {
            uni.navigateTo({
                url: '/packageA/loginAgain/loginAgain'
            });
        }
        if (response.data.code !== 200) {
            uni.showToast({
                title: response.data.message,
                icon: "none",
                duration: 2000
            });
        }
        return response.data;
    }, (response) => {
        uni.hideLoading();
        return Promise.reject(response)
    })
}
export default { install }
h5/utils/login.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
import Vue from 'vue'
// åˆ¤æ–­æ˜¯å¦ç™»å½•
export function isLogin(type) {
    // console.log('判断是否登录');
    if (type === 'empty') {
        loginAction()
        return
    }
    if (!uni.getStorageSync('token')) {
        console.log('未登录');
        loginAction()
    } else {
        console.log('已登录');
        let oldTime = Number(uni.getStorageSync('time'))
        let s = (new Date().valueOf() - oldTime) / 1000
        let h = s / 60 / 60
        console.log(h)
        if (h >= 120) {
            console.log('过期');
            loginAction()
        } else {
            console.log('未过期');
            Vue.prototype.$reslove()
        }
    }
}
function loginAction() {
    // console.log('getProvider å‰');
    uni.getProvider({
        service: 'oauth',
        success: function(res) {
            // console.log('获取授权成功');
            uni.login({
                provider: res.provider,
                scopes: 'auth_user',
                success: function(loginRes) {
                    // #ifdef MP-WEIXIN
                        // wxLogin({ code: loginRes.code })
                        //     .then(resData => {
                        //         uni.setStorageSync('token', resData.data.token);
                        //         uni.setStorageSync('avatarUrl', resData.data.member.avatarUrl);
                        //         uni.setStorageSync('nickName', resData.data.member.nickName);
                        //         uni.setStorageSync('realName', resData.data.member.realName);
                        //         uni.setStorageSync('gender', resData.data.member.gender);
                        //         uni.setStorageSync('mobile', resData.data.member.mobile);
                        //         uni.setStorageSync('sessionKey', resData.data.sessionKey);
                        //         uni.setStorageSync('time', new Date().valueOf());
                        //         Vue.prototype.$reslove()
                        //     })
                    // #endif
                }
            })
        }
    })
}
h5/utils/meetingHttp.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
import { baseUrl } from './http.api'
const install = (Vue, vm) => {
    uni.$u.http.setConfig((config) => {
        config.baseURL = baseUrl
        config.timeout = 60000
        return config
    })
    let ordinaryLogin = (params = {}) => uni.$u.http.get('web/account/ordinaryLogin', { params })
    let wxEmpower = (params = {}) => uni.$u.http.get('web/account/wxEmpower', { params })
    let editUserInfo = (data = {}) => vm.$u.http.post('web/account/editUserInfo', data)
    let getUserInfo = (params = {}) => vm.$u.http.get('web/account/getUserInfo', { params })
    let roomsList = (params = {}) => vm.$u.http.get('web/rooms/roomsList', { params })
    let getRoomUseTime = (data = {}) => vm.$u.http.post('web/rooms/getRoomUseTime', data)
    let userPage = (data = {}) => vm.$u.http.post('web/meeting/userPage', data)
    let getRoomDetail = (params = {}) => vm.$u.http.get('web/rooms/getRoomDetail', { params })
    let reservationMeeting = (data = {}) => vm.$u.http.post('web/meeting/reservationMeeting', data)
    let meetingDetail = (params = {}) => vm.$u.http.get('web/meeting/meetingDetail', { params })
    let getQrCode = (params = {}) => vm.$u.http.get('web/meeting/getQrCode', { params })
    let reservationCancel = (params = {}) => vm.$u.http.get('web/meeting/reservationCancel', { params })
    let resetPwd = (data = {}) => vm.$u.http.post('web/account/resetPwd', data)
    let myMeetingPage = (data = {}) => vm.$u.http.post('web/meeting/myMeetingPage', data)
    let myRoomsPage = (data = {}) => vm.$u.http.post('web/rooms/myRoomsPage', data)
    let findNoticePage = (data = {}) => vm.$u.http.post('web/notice/findNoticePage', data)
    let getMemberDTO = (params = {}) => vm.$u.http.get('web/notice/getMemberDTO', { params })
    let findNewNotice = (params = {}) => vm.$u.http.get('web/notice/findNewNotice', { params })
    let monthMeeting = (params = {}) => vm.$u.http.get('web/meeting/monthMeeting', { params })
    let roomsGetQrCode = (params = {}) => vm.$u.http.get('web/rooms/getQrCode', { params })
    let getSystemDictData = (params = {}) => vm.$u.http.get('web/util/getSystemDictData', { params })
    let getQrCodeImg = (params = {}) => vm.$u.http.get('web/meeting/getQrCodeImg', { params })
    let visitorLogin = (params = {}) => vm.$u.http.get('web/account/visitorLogin', { params })
    let visitorWxPhone = (data = {}) => vm.$u.http.post('web/account/visitorWxPhone', data)
    let getNoticeDetail = (params = {}) => vm.$u.http.get('web/notice/getNoticeDetail', { params })
    vm.$u.api = {
        ordinaryLogin,
        wxEmpower,
        editUserInfo,
        getUserInfo,
        roomsList,
        getRoomUseTime,
        userPage,
        getRoomDetail,
        reservationMeeting,
        meetingDetail,
        getQrCode,
        reservationCancel,
        resetPwd,
        myMeetingPage,
        myRoomsPage,
        findNoticePage,
        getMemberDTO,
        findNewNotice,
        monthMeeting,
        roomsGetQrCode,
        getSystemDictData,
        getQrCodeImg,
        visitorLogin,
        visitorWxPhone,
        getNoticeDetail
    }
}
export default { install }
h5/utils/qrcode.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1201 @@
let QRCode = {};
(function () {
    /**
     * èŽ·å–å•ä¸ªå­—ç¬¦çš„utf8编码
     * unicode BMP平面约65535个字符
     * @param {num} code
     * return {array}
     */
    function unicodeFormat8(code) {
        // 1 byte
        var c0, c1, c2;
        if (code < 128) {
            return [code];
            // 2 bytes
        } else if (code < 2048) {
            c0 = 192 + (code >> 6);
            c1 = 128 + (code & 63);
            return [c0, c1];
            // 3 bytes
        } else {
            c0 = 224 + (code >> 12);
            c1 = 128 + (code >> 6 & 63);
            c2 = 128 + (code & 63);
            return [c0, c1, c2];
        }
    }
    /**
     * èŽ·å–å­—ç¬¦ä¸²çš„utf8编码字节串
     * @param {string} string
     * @return {array}
     */
    function getUTF8Bytes(string) {
        var utf8codes = [];
        for (var i = 0; i < string.length; i++) {
            var code = string.charCodeAt(i);
            var utf8 = unicodeFormat8(code);
            for (var j = 0; j < utf8.length; j++) {
                utf8codes.push(utf8[j]);
            }
        }
        return utf8codes;
    }
    /**
     * äºŒç»´ç ç®—法实现
     * @param {string} data              è¦ç¼–码的信息字符串
     * @param {num} errorCorrectLevel çº é”™ç­‰çº§
     */
    function QRCodeAlg(data, errorCorrectLevel) {
        this.typeNumber = -1; //版本
        this.errorCorrectLevel = errorCorrectLevel;
        this.modules = null; //二维矩阵,存放最终结果
        this.moduleCount = 0; //矩阵大小
        this.dataCache = null; //数据缓存
        this.rsBlocks = null; //版本数据信息
        this.totalDataCount = -1; //可使用的数据量
        this.data = data;
        this.utf8bytes = getUTF8Bytes(data);
        this.make();
    }
    QRCodeAlg.prototype = {
        constructor: QRCodeAlg,
        /**
         * èŽ·å–äºŒç»´ç çŸ©é˜µå¤§å°
         * @return {num} çŸ©é˜µå¤§å°
         */
        getModuleCount: function () {
            return this.moduleCount;
        },
        /**
         * ç¼–码
         */
        make: function () {
            this.getRightType();
            this.dataCache = this.createData();
            this.createQrcode();
        },
        /**
         * è®¾ç½®äºŒä½çŸ©é˜µåŠŸèƒ½å›¾å½¢
         * @param  {bool} test è¡¨ç¤ºæ˜¯å¦åœ¨å¯»æ‰¾æœ€å¥½æŽ©è†œé˜¶æ®µ
         * @param  {num} maskPattern æŽ©è†œçš„版本
         */
        makeImpl: function (maskPattern) {
            this.moduleCount = this.typeNumber * 4 + 17;
            this.modules = new Array(this.moduleCount);
            for (var row = 0; row < this.moduleCount; row++) {
                this.modules[row] = new Array(this.moduleCount);
            }
            this.setupPositionProbePattern(0, 0);
            this.setupPositionProbePattern(this.moduleCount - 7, 0);
            this.setupPositionProbePattern(0, this.moduleCount - 7);
            this.setupPositionAdjustPattern();
            this.setupTimingPattern();
            this.setupTypeInfo(true, maskPattern);
            if (this.typeNumber >= 7) {
                this.setupTypeNumber(true);
            }
            this.mapData(this.dataCache, maskPattern);
        },
        /**
         * è®¾ç½®äºŒç»´ç çš„位置探测图形
         * @param  {num} row æŽ¢æµ‹å›¾å½¢çš„中心横坐标
         * @param  {num} col æŽ¢æµ‹å›¾å½¢çš„中心纵坐标
         */
        setupPositionProbePattern: function (row, col) {
            for (var r = -1; r <= 7; r++) {
                if (row + r <= -1 || this.moduleCount <= row + r) continue;
                for (var c = -1; c <= 7; c++) {
                    if (col + c <= -1 || this.moduleCount <= col + c) continue;
                    if ((0 <= r && r <= 6 && (c == 0 || c == 6)) || (0 <= c && c <= 6 && (r == 0 || r == 6)) || (2 <= r && r <= 4 && 2 <= c && c <= 4)) {
                        this.modules[row + r][col + c] = true;
                    } else {
                        this.modules[row + r][col + c] = false;
                    }
                }
            }
        },
        /**
         * åˆ›å»ºäºŒç»´ç 
         * @return {[type]} [description]
         */
        createQrcode: function () {
            var minLostPoint = 0;
            var pattern = 0;
            var bestModules = null;
            for (var i = 0; i < 8; i++) {
                this.makeImpl(i);
                var lostPoint = QRUtil.getLostPoint(this);
                if (i == 0 || minLostPoint > lostPoint) {
                    minLostPoint = lostPoint;
                    pattern = i;
                    bestModules = this.modules;
                }
            }
            this.modules = bestModules;
            this.setupTypeInfo(false, pattern);
            if (this.typeNumber >= 7) {
                this.setupTypeNumber(false);
            }
        },
        /**
         * è®¾ç½®å®šä½å›¾å½¢
         * @return {[type]} [description]
         */
        setupTimingPattern: function () {
            for (var r = 8; r < this.moduleCount - 8; r++) {
                if (this.modules[r][6] != null) {
                    continue;
                }
                this.modules[r][6] = (r % 2 == 0);
                if (this.modules[6][r] != null) {
                    continue;
                }
                this.modules[6][r] = (r % 2 == 0);
            }
        },
        /**
         * è®¾ç½®çŸ«æ­£å›¾å½¢
         * @return {[type]} [description]
         */
        setupPositionAdjustPattern: function () {
            var pos = QRUtil.getPatternPosition(this.typeNumber);
            for (var i = 0; i < pos.length; i++) {
                for (var j = 0; j < pos.length; j++) {
                    var row = pos[i];
                    var col = pos[j];
                    if (this.modules[row][col] != null) {
                        continue;
                    }
                    for (var r = -2; r <= 2; r++) {
                        for (var c = -2; c <= 2; c++) {
                            if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) {
                                this.modules[row + r][col + c] = true;
                            } else {
                                this.modules[row + r][col + c] = false;
                            }
                        }
                    }
                }
            }
        },
        /**
         * è®¾ç½®ç‰ˆæœ¬ä¿¡æ¯ï¼ˆ7以上版本才有)
         * @param  {bool} test æ˜¯å¦å¤„于判断最佳掩膜阶段
         * @return {[type]}      [description]
         */
        setupTypeNumber: function (test) {
            var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
            for (var i = 0; i < 18; i++) {
                var mod = (!test && ((bits >> i) & 1) == 1);
                this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
                this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
            }
        },
        /**
         * è®¾ç½®æ ¼å¼ä¿¡æ¯ï¼ˆçº é”™ç­‰çº§å’ŒæŽ©è†œç‰ˆæœ¬ï¼‰
         * @param  {bool} test
         * @param  {num} maskPattern æŽ©è†œç‰ˆæœ¬
         * @return {}
         */
        setupTypeInfo: function (test, maskPattern) {
            var data = (QRErrorCorrectLevel[this.errorCorrectLevel] << 3) | maskPattern;
            var bits = QRUtil.getBCHTypeInfo(data);
            // vertical
            for (var i = 0; i < 15; i++) {
                var mod = (!test && ((bits >> i) & 1) == 1);
                if (i < 6) {
                    this.modules[i][8] = mod;
                } else if (i < 8) {
                    this.modules[i + 1][8] = mod;
                } else {
                    this.modules[this.moduleCount - 15 + i][8] = mod;
                }
                // horizontal
                var mod = (!test && ((bits >> i) & 1) == 1);
                if (i < 8) {
                    this.modules[8][this.moduleCount - i - 1] = mod;
                } else if (i < 9) {
                    this.modules[8][15 - i - 1 + 1] = mod;
                } else {
                    this.modules[8][15 - i - 1] = mod;
                }
            }
            // fixed module
            this.modules[this.moduleCount - 8][8] = (!test);
        },
        /**
         * æ•°æ®ç¼–码
         * @return {[type]} [description]
         */
        createData: function () {
            var buffer = new QRBitBuffer();
            var lengthBits = this.typeNumber > 9 ? 16 : 8;
            buffer.put(4, 4); //添加模式
            buffer.put(this.utf8bytes.length, lengthBits);
            for (var i = 0, l = this.utf8bytes.length; i < l; i++) {
                buffer.put(this.utf8bytes[i], 8);
            }
            if (buffer.length + 4 <= this.totalDataCount * 8) {
                buffer.put(0, 4);
            }
            // padding
            while (buffer.length % 8 != 0) {
                buffer.putBit(false);
            }
            // padding
            while (true) {
                if (buffer.length >= this.totalDataCount * 8) {
                    break;
                }
                buffer.put(QRCodeAlg.PAD0, 8);
                if (buffer.length >= this.totalDataCount * 8) {
                    break;
                }
                buffer.put(QRCodeAlg.PAD1, 8);
            }
            return this.createBytes(buffer);
        },
        /**
         * çº é”™ç ç¼–码
         * @param  {buffer} buffer æ•°æ®ç¼–码
         * @return {[type]}
         */
        createBytes: function (buffer) {
            var offset = 0;
            var maxDcCount = 0;
            var maxEcCount = 0;
            var length = this.rsBlock.length / 3;
            var rsBlocks = new Array();
            for (var i = 0; i < length; i++) {
                var count = this.rsBlock[i * 3 + 0];
                var totalCount = this.rsBlock[i * 3 + 1];
                var dataCount = this.rsBlock[i * 3 + 2];
                for (var j = 0; j < count; j++) {
                    rsBlocks.push([dataCount, totalCount]);
                }
            }
            var dcdata = new Array(rsBlocks.length);
            var ecdata = new Array(rsBlocks.length);
            for (var r = 0; r < rsBlocks.length; r++) {
                var dcCount = rsBlocks[r][0];
                var ecCount = rsBlocks[r][1] - dcCount;
                maxDcCount = Math.max(maxDcCount, dcCount);
                maxEcCount = Math.max(maxEcCount, ecCount);
                dcdata[r] = new Array(dcCount);
                for (var i = 0; i < dcdata[r].length; i++) {
                    dcdata[r][i] = 0xff & buffer.buffer[i + offset];
                }
                offset += dcCount;
                var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
                var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
                var modPoly = rawPoly.mod(rsPoly);
                ecdata[r] = new Array(rsPoly.getLength() - 1);
                for (var i = 0; i < ecdata[r].length; i++) {
                    var modIndex = i + modPoly.getLength() - ecdata[r].length;
                    ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0;
                }
            }
            var data = new Array(this.totalDataCount);
            var index = 0;
            for (var i = 0; i < maxDcCount; i++) {
                for (var r = 0; r < rsBlocks.length; r++) {
                    if (i < dcdata[r].length) {
                        data[index++] = dcdata[r][i];
                    }
                }
            }
            for (var i = 0; i < maxEcCount; i++) {
                for (var r = 0; r < rsBlocks.length; r++) {
                    if (i < ecdata[r].length) {
                        data[index++] = ecdata[r][i];
                    }
                }
            }
            return data;
        },
        /**
         * å¸ƒç½®æ¨¡å—,构建最终信息
         * @param  {} data
         * @param  {} maskPattern
         * @return {}
         */
        mapData: function (data, maskPattern) {
            var inc = -1;
            var row = this.moduleCount - 1;
            var bitIndex = 7;
            var byteIndex = 0;
            for (var col = this.moduleCount - 1; col > 0; col -= 2) {
                if (col == 6) col--;
                while (true) {
                    for (var c = 0; c < 2; c++) {
                        if (this.modules[row][col - c] == null) {
                            var dark = false;
                            if (byteIndex < data.length) {
                                dark = (((data[byteIndex] >>> bitIndex) & 1) == 1);
                            }
                            var mask = QRUtil.getMask(maskPattern, row, col - c);
                            if (mask) {
                                dark = !dark;
                            }
                            this.modules[row][col - c] = dark;
                            bitIndex--;
                            if (bitIndex == -1) {
                                byteIndex++;
                                bitIndex = 7;
                            }
                        }
                    }
                    row += inc;
                    if (row < 0 || this.moduleCount <= row) {
                        row -= inc;
                        inc = -inc;
                        break;
                    }
                }
            }
        }
    };
    /**
     * å¡«å……字段
     */
    QRCodeAlg.PAD0 = 0xEC;
    QRCodeAlg.PAD1 = 0x11;
    //---------------------------------------------------------------------
    // çº é”™ç­‰çº§å¯¹åº”的编码
    //---------------------------------------------------------------------
    var QRErrorCorrectLevel = [1, 0, 3, 2];
    //---------------------------------------------------------------------
    // æŽ©è†œç‰ˆæœ¬
    //---------------------------------------------------------------------
    var QRMaskPattern = {
        PATTERN000: 0,
        PATTERN001: 1,
        PATTERN010: 2,
        PATTERN011: 3,
        PATTERN100: 4,
        PATTERN101: 5,
        PATTERN110: 6,
        PATTERN111: 7
    };
    //---------------------------------------------------------------------
    // å·¥å…·ç±»
    //---------------------------------------------------------------------
    var QRUtil = {
        /*
        æ¯ä¸ªç‰ˆæœ¬çŸ«æ­£å›¾å½¢çš„位置
         */
        PATTERN_POSITION_TABLE: [
            [],
            [6, 18],
            [6, 22],
            [6, 26],
            [6, 30],
            [6, 34],
            [6, 22, 38],
            [6, 24, 42],
            [6, 26, 46],
            [6, 28, 50],
            [6, 30, 54],
            [6, 32, 58],
            [6, 34, 62],
            [6, 26, 46, 66],
            [6, 26, 48, 70],
            [6, 26, 50, 74],
            [6, 30, 54, 78],
            [6, 30, 56, 82],
            [6, 30, 58, 86],
            [6, 34, 62, 90],
            [6, 28, 50, 72, 94],
            [6, 26, 50, 74, 98],
            [6, 30, 54, 78, 102],
            [6, 28, 54, 80, 106],
            [6, 32, 58, 84, 110],
            [6, 30, 58, 86, 114],
            [6, 34, 62, 90, 118],
            [6, 26, 50, 74, 98, 122],
            [6, 30, 54, 78, 102, 126],
            [6, 26, 52, 78, 104, 130],
            [6, 30, 56, 82, 108, 134],
            [6, 34, 60, 86, 112, 138],
            [6, 30, 58, 86, 114, 142],
            [6, 34, 62, 90, 118, 146],
            [6, 30, 54, 78, 102, 126, 150],
            [6, 24, 50, 76, 102, 128, 154],
            [6, 28, 54, 80, 106, 132, 158],
            [6, 32, 58, 84, 110, 136, 162],
            [6, 26, 54, 82, 110, 138, 166],
            [6, 30, 58, 86, 114, 142, 170]
        ],
        G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
        G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
        G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
        /*
        BCH编码格式信息
         */
        getBCHTypeInfo: function (data) {
            var d = data << 10;
            while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
                d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15)));
            }
            return ((data << 10) | d) ^ QRUtil.G15_MASK;
        },
        /*
        BCH编码版本信息
         */
        getBCHTypeNumber: function (data) {
            var d = data << 12;
            while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
                d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18)));
            }
            return (data << 12) | d;
        },
        /*
        èŽ·å–BCH位信息
         */
        getBCHDigit: function (data) {
            var digit = 0;
            while (data != 0) {
                digit++;
                data >>>= 1;
            }
            return digit;
        },
        /*
        èŽ·å–ç‰ˆæœ¬å¯¹åº”çš„çŸ«æ­£å›¾å½¢ä½ç½®
         */
        getPatternPosition: function (typeNumber) {
            return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
        },
        /*
        æŽ©è†œç®—法
         */
        getMask: function (maskPattern, i, j) {
            switch (maskPattern) {
                case QRMaskPattern.PATTERN000:
                    return (i + j) % 2 == 0;
                case QRMaskPattern.PATTERN001:
                    return i % 2 == 0;
                case QRMaskPattern.PATTERN010:
                    return j % 3 == 0;
                case QRMaskPattern.PATTERN011:
                    return (i + j) % 3 == 0;
                case QRMaskPattern.PATTERN100:
                    return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
                case QRMaskPattern.PATTERN101:
                    return (i * j) % 2 + (i * j) % 3 == 0;
                case QRMaskPattern.PATTERN110:
                    return ((i * j) % 2 + (i * j) % 3) % 2 == 0;
                case QRMaskPattern.PATTERN111:
                    return ((i * j) % 3 + (i + j) % 2) % 2 == 0;
                default:
                    throw new Error("bad maskPattern:" + maskPattern);
            }
        },
        /*
        èŽ·å–RS的纠错多项式
         */
        getErrorCorrectPolynomial: function (errorCorrectLength) {
            var a = new QRPolynomial([1], 0);
            for (var i = 0; i < errorCorrectLength; i++) {
                a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
            }
            return a;
        },
        /*
        èŽ·å–è¯„ä»·
         */
        getLostPoint: function (qrCode) {
            var moduleCount = qrCode.getModuleCount(),
                lostPoint = 0,
                darkCount = 0;
            for (var row = 0; row < moduleCount; row++) {
                var sameCount = 0;
                var head = qrCode.modules[row][0];
                for (var col = 0; col < moduleCount; col++) {
                    var current = qrCode.modules[row][col];
                    //level 3 è¯„ä»·
                    if (col < moduleCount - 6) {
                        if (current && !qrCode.modules[row][col + 1] && qrCode.modules[row][col + 2] && qrCode.modules[row][col + 3] && qrCode.modules[row][col + 4] && !qrCode.modules[row][col + 5] && qrCode.modules[row][col + 6]) {
                            if (col < moduleCount - 10) {
                                if (qrCode.modules[row][col + 7] && qrCode.modules[row][col + 8] && qrCode.modules[row][col + 9] && qrCode.modules[row][col + 10]) {
                                    lostPoint += 40;
                                }
                            } else if (col > 3) {
                                if (qrCode.modules[row][col - 1] && qrCode.modules[row][col - 2] && qrCode.modules[row][col - 3] && qrCode.modules[row][col - 4]) {
                                    lostPoint += 40;
                                }
                            }
                        }
                    }
                    //level 2 è¯„ä»·
                    if ((row < moduleCount - 1) && (col < moduleCount - 1)) {
                        var count = 0;
                        if (current) count++;
                        if (qrCode.modules[row + 1][col]) count++;
                        if (qrCode.modules[row][col + 1]) count++;
                        if (qrCode.modules[row + 1][col + 1]) count++;
                        if (count == 0 || count == 4) {
                            lostPoint += 3;
                        }
                    }
                    //level 1 è¯„ä»·
                    if (head ^ current) {
                        sameCount++;
                    } else {
                        head = current;
                        if (sameCount >= 5) {
                            lostPoint += (3 + sameCount - 5);
                        }
                        sameCount = 1;
                    }
                    //level 4 è¯„ä»·
                    if (current) {
                        darkCount++;
                    }
                }
            }
            for (var col = 0; col < moduleCount; col++) {
                var sameCount = 0;
                var head = qrCode.modules[0][col];
                for (var row = 0; row < moduleCount; row++) {
                    var current = qrCode.modules[row][col];
                    //level 3 è¯„ä»·
                    if (row < moduleCount - 6) {
                        if (current && !qrCode.modules[row + 1][col] && qrCode.modules[row + 2][col] && qrCode.modules[row + 3][col] && qrCode.modules[row + 4][col] && !qrCode.modules[row + 5][col] && qrCode.modules[row + 6][col]) {
                            if (row < moduleCount - 10) {
                                if (qrCode.modules[row + 7][col] && qrCode.modules[row + 8][col] && qrCode.modules[row + 9][col] && qrCode.modules[row + 10][col]) {
                                    lostPoint += 40;
                                }
                            } else if (row > 3) {
                                if (qrCode.modules[row - 1][col] && qrCode.modules[row - 2][col] && qrCode.modules[row - 3][col] && qrCode.modules[row - 4][col]) {
                                    lostPoint += 40;
                                }
                            }
                        }
                    }
                    //level 1 è¯„ä»·
                    if (head ^ current) {
                        sameCount++;
                    } else {
                        head = current;
                        if (sameCount >= 5) {
                            lostPoint += (3 + sameCount - 5);
                        }
                        sameCount = 1;
                    }
                }
            }
            // LEVEL4
            var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
            lostPoint += ratio * 10;
            return lostPoint;
        }
    };
    //---------------------------------------------------------------------
    // QRMath使用的数学工具
    //---------------------------------------------------------------------
    var QRMath = {
        /*
        å°†n转化为a^m
         */
        glog: function (n) {
            if (n < 1) {
                throw new Error("glog(" + n + ")");
            }
            return QRMath.LOG_TABLE[n];
        },
        /*
        å°†a^m转化为n
         */
        gexp: function (n) {
            while (n < 0) {
                n += 255;
            }
            while (n >= 256) {
                n -= 255;
            }
            return QRMath.EXP_TABLE[n];
        },
        EXP_TABLE: new Array(256),
        LOG_TABLE: new Array(256)
    };
    for (var i = 0; i < 8; i++) {
        QRMath.EXP_TABLE[i] = 1 << i;
    }
    for (var i = 8; i < 256; i++) {
        QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^ QRMath.EXP_TABLE[i - 5] ^ QRMath.EXP_TABLE[i - 6] ^ QRMath.EXP_TABLE[i - 8];
    }
    for (var i = 0; i < 255; i++) {
        QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
    }
    //---------------------------------------------------------------------
    // QRPolynomial å¤šé¡¹å¼
    //---------------------------------------------------------------------
    /**
     * å¤šé¡¹å¼ç±»
     * @param {Array} num   ç³»æ•°
     * @param {num} shift a^shift
     */
    function QRPolynomial(num, shift) {
        if (num.length == undefined) {
            throw new Error(num.length + "/" + shift);
        }
        var offset = 0;
        while (offset < num.length && num[offset] == 0) {
            offset++;
        }
        this.num = new Array(num.length - offset + shift);
        for (var i = 0; i < num.length - offset; i++) {
            this.num[i] = num[i + offset];
        }
    }
    QRPolynomial.prototype = {
        get: function (index) {
            return this.num[index];
        },
        getLength: function () {
            return this.num.length;
        },
        /**
         * å¤šé¡¹å¼ä¹˜æ³•
         * @param  {QRPolynomial} e è¢«ä¹˜å¤šé¡¹å¼
         * @return {[type]}   [description]
         */
        multiply: function (e) {
            var num = new Array(this.getLength() + e.getLength() - 1);
            for (var i = 0; i < this.getLength(); i++) {
                for (var j = 0; j < e.getLength(); j++) {
                    num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
                }
            }
            return new QRPolynomial(num, 0);
        },
        /**
         * å¤šé¡¹å¼æ¨¡è¿ç®—
         * @param  {QRPolynomial} e æ¨¡å¤šé¡¹å¼
         * @return {}
         */
        mod: function (e) {
            var tl = this.getLength(),
                el = e.getLength();
            if (tl - el < 0) {
                return this;
            }
            var num = new Array(tl);
            for (var i = 0; i < tl; i++) {
                num[i] = this.get(i);
            }
            while (num.length >= el) {
                var ratio = QRMath.glog(num[0]) - QRMath.glog(e.get(0));
                for (var i = 0; i < e.getLength(); i++) {
                    num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
                }
                while (num[0] == 0) {
                    num.shift();
                }
            }
            return new QRPolynomial(num, 0);
        }
    };
    //---------------------------------------------------------------------
    // RS_BLOCK_TABLE
    //---------------------------------------------------------------------
    /*
    äºŒç»´ç å„个版本信息[块数, æ¯å—中的数据块数, æ¯å—中的信息块数]
     */
    var RS_BLOCK_TABLE = [
        // L
        // M
        // Q
        // H
        // 1
        [1, 26, 19],
        [1, 26, 16],
        [1, 26, 13],
        [1, 26, 9],
        // 2
        [1, 44, 34],
        [1, 44, 28],
        [1, 44, 22],
        [1, 44, 16],
        // 3
        [1, 70, 55],
        [1, 70, 44],
        [2, 35, 17],
        [2, 35, 13],
        // 4
        [1, 100, 80],
        [2, 50, 32],
        [2, 50, 24],
        [4, 25, 9],
        // 5
        [1, 134, 108],
        [2, 67, 43],
        [2, 33, 15, 2, 34, 16],
        [2, 33, 11, 2, 34, 12],
        // 6
        [2, 86, 68],
        [4, 43, 27],
        [4, 43, 19],
        [4, 43, 15],
        // 7
        [2, 98, 78],
        [4, 49, 31],
        [2, 32, 14, 4, 33, 15],
        [4, 39, 13, 1, 40, 14],
        // 8
        [2, 121, 97],
        [2, 60, 38, 2, 61, 39],
        [4, 40, 18, 2, 41, 19],
        [4, 40, 14, 2, 41, 15],
        // 9
        [2, 146, 116],
        [3, 58, 36, 2, 59, 37],
        [4, 36, 16, 4, 37, 17],
        [4, 36, 12, 4, 37, 13],
        // 10
        [2, 86, 68, 2, 87, 69],
        [4, 69, 43, 1, 70, 44],
        [6, 43, 19, 2, 44, 20],
        [6, 43, 15, 2, 44, 16],
        // 11
        [4, 101, 81],
        [1, 80, 50, 4, 81, 51],
        [4, 50, 22, 4, 51, 23],
        [3, 36, 12, 8, 37, 13],
        // 12
        [2, 116, 92, 2, 117, 93],
        [6, 58, 36, 2, 59, 37],
        [4, 46, 20, 6, 47, 21],
        [7, 42, 14, 4, 43, 15],
        // 13
        [4, 133, 107],
        [8, 59, 37, 1, 60, 38],
        [8, 44, 20, 4, 45, 21],
        [12, 33, 11, 4, 34, 12],
        // 14
        [3, 145, 115, 1, 146, 116],
        [4, 64, 40, 5, 65, 41],
        [11, 36, 16, 5, 37, 17],
        [11, 36, 12, 5, 37, 13],
        // 15
        [5, 109, 87, 1, 110, 88],
        [5, 65, 41, 5, 66, 42],
        [5, 54, 24, 7, 55, 25],
        [11, 36, 12],
        // 16
        [5, 122, 98, 1, 123, 99],
        [7, 73, 45, 3, 74, 46],
        [15, 43, 19, 2, 44, 20],
        [3, 45, 15, 13, 46, 16],
        // 17
        [1, 135, 107, 5, 136, 108],
        [10, 74, 46, 1, 75, 47],
        [1, 50, 22, 15, 51, 23],
        [2, 42, 14, 17, 43, 15],
        // 18
        [5, 150, 120, 1, 151, 121],
        [9, 69, 43, 4, 70, 44],
        [17, 50, 22, 1, 51, 23],
        [2, 42, 14, 19, 43, 15],
        // 19
        [3, 141, 113, 4, 142, 114],
        [3, 70, 44, 11, 71, 45],
        [17, 47, 21, 4, 48, 22],
        [9, 39, 13, 16, 40, 14],
        // 20
        [3, 135, 107, 5, 136, 108],
        [3, 67, 41, 13, 68, 42],
        [15, 54, 24, 5, 55, 25],
        [15, 43, 15, 10, 44, 16],
        // 21
        [4, 144, 116, 4, 145, 117],
        [17, 68, 42],
        [17, 50, 22, 6, 51, 23],
        [19, 46, 16, 6, 47, 17],
        // 22
        [2, 139, 111, 7, 140, 112],
        [17, 74, 46],
        [7, 54, 24, 16, 55, 25],
        [34, 37, 13],
        // 23
        [4, 151, 121, 5, 152, 122],
        [4, 75, 47, 14, 76, 48],
        [11, 54, 24, 14, 55, 25],
        [16, 45, 15, 14, 46, 16],
        // 24
        [6, 147, 117, 4, 148, 118],
        [6, 73, 45, 14, 74, 46],
        [11, 54, 24, 16, 55, 25],
        [30, 46, 16, 2, 47, 17],
        // 25
        [8, 132, 106, 4, 133, 107],
        [8, 75, 47, 13, 76, 48],
        [7, 54, 24, 22, 55, 25],
        [22, 45, 15, 13, 46, 16],
        // 26
        [10, 142, 114, 2, 143, 115],
        [19, 74, 46, 4, 75, 47],
        [28, 50, 22, 6, 51, 23],
        [33, 46, 16, 4, 47, 17],
        // 27
        [8, 152, 122, 4, 153, 123],
        [22, 73, 45, 3, 74, 46],
        [8, 53, 23, 26, 54, 24],
        [12, 45, 15, 28, 46, 16],
        // 28
        [3, 147, 117, 10, 148, 118],
        [3, 73, 45, 23, 74, 46],
        [4, 54, 24, 31, 55, 25],
        [11, 45, 15, 31, 46, 16],
        // 29
        [7, 146, 116, 7, 147, 117],
        [21, 73, 45, 7, 74, 46],
        [1, 53, 23, 37, 54, 24],
        [19, 45, 15, 26, 46, 16],
        // 30
        [5, 145, 115, 10, 146, 116],
        [19, 75, 47, 10, 76, 48],
        [15, 54, 24, 25, 55, 25],
        [23, 45, 15, 25, 46, 16],
        // 31
        [13, 145, 115, 3, 146, 116],
        [2, 74, 46, 29, 75, 47],
        [42, 54, 24, 1, 55, 25],
        [23, 45, 15, 28, 46, 16],
        // 32
        [17, 145, 115],
        [10, 74, 46, 23, 75, 47],
        [10, 54, 24, 35, 55, 25],
        [19, 45, 15, 35, 46, 16],
        // 33
        [17, 145, 115, 1, 146, 116],
        [14, 74, 46, 21, 75, 47],
        [29, 54, 24, 19, 55, 25],
        [11, 45, 15, 46, 46, 16],
        // 34
        [13, 145, 115, 6, 146, 116],
        [14, 74, 46, 23, 75, 47],
        [44, 54, 24, 7, 55, 25],
        [59, 46, 16, 1, 47, 17],
        // 35
        [12, 151, 121, 7, 152, 122],
        [12, 75, 47, 26, 76, 48],
        [39, 54, 24, 14, 55, 25],
        [22, 45, 15, 41, 46, 16],
        // 36
        [6, 151, 121, 14, 152, 122],
        [6, 75, 47, 34, 76, 48],
        [46, 54, 24, 10, 55, 25],
        [2, 45, 15, 64, 46, 16],
        // 37
        [17, 152, 122, 4, 153, 123],
        [29, 74, 46, 14, 75, 47],
        [49, 54, 24, 10, 55, 25],
        [24, 45, 15, 46, 46, 16],
        // 38
        [4, 152, 122, 18, 153, 123],
        [13, 74, 46, 32, 75, 47],
        [48, 54, 24, 14, 55, 25],
        [42, 45, 15, 32, 46, 16],
        // 39
        [20, 147, 117, 4, 148, 118],
        [40, 75, 47, 7, 76, 48],
        [43, 54, 24, 22, 55, 25],
        [10, 45, 15, 67, 46, 16],
        // 40
        [19, 148, 118, 6, 149, 119],
        [18, 75, 47, 31, 76, 48],
        [34, 54, 24, 34, 55, 25],
        [20, 45, 15, 61, 46, 16]
    ];
    /**
     * æ ¹æ®æ•°æ®èŽ·å–å¯¹åº”ç‰ˆæœ¬
     * @return {[type]} [description]
     */
    QRCodeAlg.prototype.getRightType = function () {
        for (var typeNumber = 1; typeNumber < 41; typeNumber++) {
            var rsBlock = RS_BLOCK_TABLE[(typeNumber - 1) * 4 + this.errorCorrectLevel];
            if (rsBlock == undefined) {
                throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + this.errorCorrectLevel);
            }
            var length = rsBlock.length / 3;
            var totalDataCount = 0;
            for (var i = 0; i < length; i++) {
                var count = rsBlock[i * 3 + 0];
                var dataCount = rsBlock[i * 3 + 2];
                totalDataCount += dataCount * count;
            }
            var lengthBytes = typeNumber > 9 ? 2 : 1;
            if (this.utf8bytes.length + lengthBytes < totalDataCount || typeNumber == 40) {
                this.typeNumber = typeNumber;
                this.rsBlock = rsBlock;
                this.totalDataCount = totalDataCount;
                break;
            }
        }
    };
    //---------------------------------------------------------------------
    // QRBitBuffer
    //---------------------------------------------------------------------
    function QRBitBuffer() {
        this.buffer = new Array();
        this.length = 0;
    }
    QRBitBuffer.prototype = {
        get: function (index) {
            var bufIndex = Math.floor(index / 8);
            return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1);
        },
        put: function (num, length) {
            for (var i = 0; i < length; i++) {
                this.putBit(((num >>> (length - i - 1)) & 1));
            }
        },
        putBit: function (bit) {
            var bufIndex = Math.floor(this.length / 8);
            if (this.buffer.length <= bufIndex) {
                this.buffer.push(0);
            }
            if (bit) {
                this.buffer[bufIndex] |= (0x80 >>> (this.length % 8));
            }
            this.length++;
        }
    };
    // xzedit
    let qrcodeAlgObjCache = [];
    /**
     * äºŒç»´ç æž„造函数,主要用于绘制
     * @param  {参数列表} opt ä¼ é€’参数
     * @return {}
     */
    QRCode = function (opt) {
        //设置默认参数
        this.options = {
            text: '',
            size: 256,
            correctLevel: 3,
            background: '#ffffff',
            foreground: '#000000',
            pdground: '#000000',
            image: '',
            imageSize: 30,
            canvasId: opt.canvasId,
            context: opt.context,
            usingComponents: opt.usingComponents,
            showLoading: opt.showLoading,
            loadingText: opt.loadingText,
        };
        if (typeof opt === 'string') { // åªç¼–码ASCII字符串
            opt = {
                text: opt
            };
        }
        if (opt) {
            for (var i in opt) {
                this.options[i] = opt[i];
            }
        }
        //使用QRCodeAlg创建二维码结构
        var qrCodeAlg = null;
        for (var i = 0, l = qrcodeAlgObjCache.length; i < l; i++) {
            if (qrcodeAlgObjCache[i].text == this.options.text && qrcodeAlgObjCache[i].text.correctLevel == this.options.correctLevel) {
                qrCodeAlg = qrcodeAlgObjCache[i].obj;
                break;
            }
        }
        if (i == l) {
            qrCodeAlg = new QRCodeAlg(this.options.text, this.options.correctLevel);
            qrcodeAlgObjCache.push({
                text: this.options.text,
                correctLevel: this.options.correctLevel,
                obj: qrCodeAlg
            });
        }
        /**
         * è®¡ç®—矩阵点的前景色
         * @param {Obj} config
         * @param {Number} config.row ç‚¹x坐标
         * @param {Number} config.col ç‚¹y坐标
         * @param {Number} config.count çŸ©é˜µå¤§å°
         * @param {Number} config.options ç»„ä»¶çš„options
         * @return {String}
         */
        let getForeGround = function (config) {
            var options = config.options;
            if (options.pdground && (
                (config.row > 1 && config.row < 5 && config.col > 1 && config.col < 5) ||
                (config.row > (config.count - 6) && config.row < (config.count - 2) && config.col > 1 && config.col < 5) ||
                (config.row > 1 && config.row < 5 && config.col > (config.count - 6) && config.col < (config.count - 2))
            )) {
                return options.pdground;
            }
            return options.foreground;
        }
        // åˆ›å»ºcanvas
        let createCanvas = function (options) {
            if (options.showLoading) {
                uni.showLoading({
                    title: options.loadingText,
                    mask: true
                });
            }
            var ctx = uni.createCanvasContext(options.canvasId, options.context);
            var count = qrCodeAlg.getModuleCount();
            var ratioSize = options.size;
            var ratioImgSize = options.imageSize;
            //计算每个点的长宽
            var tileW = (ratioSize / count).toPrecision(4);
            var tileH = (ratioSize / count).toPrecision(4);
            //绘制
            for (var row = 0; row < count; row++) {
                for (var col = 0; col < count; col++) {
                    var w = (Math.ceil((col + 1) * tileW) - Math.floor(col * tileW));
                    var h = (Math.ceil((row + 1) * tileW) - Math.floor(row * tileW));
                    var foreground = getForeGround({
                        row: row,
                        col: col,
                        count: count,
                        options: options
                    });
                    ctx.setFillStyle(qrCodeAlg.modules[row][col] ? foreground : options.background);
                    ctx.fillRect(Math.round(col * tileW), Math.round(row * tileH), w, h);
                }
            }
            if (options.image) {
                var x = Number(((ratioSize - ratioImgSize) / 2).toFixed(2));
                var y = Number(((ratioSize - ratioImgSize) / 2).toFixed(2));
                drawRoundedRect(ctx, x, y, ratioImgSize, ratioImgSize, 2, 6, true, true)
                ctx.drawImage(options.image, x, y, ratioImgSize, ratioImgSize);
                // ç”»åœ†è§’矩形
                function drawRoundedRect(ctxi, x, y, width, height, r, lineWidth, fill, stroke) {
                    ctxi.setLineWidth(lineWidth);
                    ctxi.setFillStyle(options.background);
                    ctxi.setStrokeStyle(options.background);
                    ctxi.beginPath(); // draw top and top right corner
                    ctxi.moveTo(x + r, y);
                    ctxi.arcTo(x + width, y, x + width, y + r, r); // draw right side and bottom right corner
                    ctxi.arcTo(x + width, y + height, x + width - r, y + height, r); // draw bottom and bottom left corner
                    ctxi.arcTo(x, y + height, x, y + height - r, r); // draw left and top left corner
                    ctxi.arcTo(x, y, x + r, y, r);
                    ctxi.closePath();
                    if (fill) {
                        ctxi.fill();
                    }
                    if (stroke) {
                        ctxi.stroke();
                    }
                }
            }
            setTimeout(() => {
                ctx.draw(true, () => {
                    // ä¿å­˜åˆ°ä¸´æ—¶åŒºåŸŸ
                    setTimeout(() => {
                        uni.canvasToTempFilePath({
                            width: options.width,
                            height: options.height,
                            destWidth: options.width,
                            destHeight: options.height,
                            canvasId: options.canvasId,
                            quality: Number(1),
                            success: function (res) {
                                if (options.cbResult) {
                                    options.cbResult(res.tempFilePath)
                                }
                            },
                            fail: function (res) {
                                if (options.cbResult) {
                                    options.cbResult(res)
                                }
                            },
                            complete: function () {
                                if (options.showLoading){
                                    uni.hideLoading();
                                }
                            },
                        }, options.context);
                    }, options.text.length + 100);
                });
            }, options.usingComponents ? 0 : 150);
        }
        createCanvas(this.options);
        // ç©ºåˆ¤å®š
        let empty = function (v) {
            let tp = typeof v,
                rt = false;
            if (tp == "number" && String(v) == "") {
                rt = true
            } else if (tp == "undefined") {
                rt = true
            } else if (tp == "object") {
                if (JSON.stringify(v) == "{}" || JSON.stringify(v) == "[]" || v == null) rt = true
            } else if (tp == "string") {
                if (v == "" || v == "undefined" || v == "null" || v == "{}" || v == "[]") rt = true
            } else if (tp == "function") {
                rt = false
            }
            return rt
        }
    };
    QRCode.prototype.clear = function (fn) {
        var ctx = uni.createCanvasContext(this.options.canvasId, this.options.context)
        ctx.clearRect(0, 0, this.options.size, this.options.size)
        ctx.draw(false, () => {
            if (fn) {
                fn()
            }
        })
    };
})()
export default QRCode
h5/utils/service.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
import { baseUrl } from "./config.js"
export const http = function (options) {
    {
        return new Promise((resolve, reject) => {
            let token = uni.getStorageSync('token') || ''
            // åœ¨ç™»å½•的时候需要储存 token uni.setStorageSync("authorization","这里是登录获取的token值")
            // uni.showLoading({
            //     title:"加载中..."
            // })
            uni.showLoading({
                title: '加载中',
                mask: true
            })
            uni.request({
                url: baseUrl + options.url,
                data: options.data || {},
                method: options.method || 'GET',
                header: options.header || {
                    // æ ¹æ®å®žé™…接口设计 key å– token æˆ–者 authorization
                    dm_user_token: token,
                    "content-type": 'application/json'
                },
                success: (res) => {
                    let data = res.data
                    // æŽ§åˆ¶å°æ˜¾ç¤ºæ•°æ®ä¿¡æ¯
                    uni.hideLoading()
                    // ç™»å½•过期
                    if (data.code !== 200) {
                        setTimeout(() => {
                            uni.showToast({
                                title: data.message,
                                icon: "none",
                                duration: 2000
                            })
                        })
                        if (data.code === 500 || data.code === 5112) {
                            uni.clearStorageSync()
                            return uni.navigateTo({
                                url: '/pages/login/login'
                            })
                        }
                        return
                    }
                    resolve(data)
                    // return response.data
                },
                fail: (err) => {
                    // é¡µé¢ä¸­å¼¹æ¡†æ˜¾ç¤ºå¤±è´¥
                    uni.showToast({
                        title: '请求接口失败'
                    })
                    // è¿”回错误消息
                    reject(err)
                    uni.hideLoading()
                    return Promise.reject(err)
                },
                catch: (e) => {
                    console.log(e)
                }
            })
        })
    }
}
h5/utils/utils.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,163 @@
/**
 * æ—¶é—´å‰åŽå‘前推算时间集合
 * @param {string:before|after} timebd:获取时间往后推,还是往前推,
 * @param {boole} haveCurrentDay:包不包含当天时间,
 * @param {number} Days:计算几天的时间,
 * @param {string:"2023-11-02"} timing:指定不指定当天的日期
 * @returns {array}数据集合
 */
export const nextDay = (timebd, haveCurrentDay, Days, timing) => {
    let today = new Date()   //获取今天的日期
    if (timing) {
      today = new Date(timing)
    }
    let date2 = new Date(today);
    let dateArray = []
    timebd=timebd ? timebd:"after"
    haveCurrentDay=haveCurrentDay ? true:false
    Days=Days ? Days:7
    function TimestampToDate2(Timestamp) {
    ã€€ã€€let now = new Date(Timestamp),
    ã€€ã€€y = now.getFullYear(),
    ã€€ã€€m = now.getMonth() + 1,
    ã€€ã€€d = now.getDate();
    ã€€ã€€return y + "-" + (m < 10 ? "0" + m : m) + "-" + (d < 10 ? "0" + d : d);
    }
    let fori=haveCurrentDay ? 0:1;
    let fortotal=haveCurrentDay ? Days:Days+1;
    for(let i = fori; i < fortotal; i++){
      let everyDay=""
      if (timebd=="after") {//未来
        everyDay=date2.setDate(today.getDate() + i)
      }else{//过去
        everyDay=date2.setDate(today.getDate() - i)
      }
      dateArray.push(TimestampToDate2(everyDay))  //获取未来7天内的日期
    }
    if (timebd=="after") {//未来
      return dateArray
    }else{//过去
      return dateArray.reverse()
    }
  }
/**
 * è¿”回两个日期之前的天数
 */
export const getDateByDays = (startDate, endDdate) => {
    let d1 = Date.parse(new Date(startDate));
    let d2 = Date.parse(new Date(endDdate));
    // æ—¶é—´æˆ³ç›¸å‡ / å¤©æ•°
    let day = parseInt((d2 - d1) / (1000 * 60 * 60 * 24));
    return day
}
// èŽ·å–å¤šå°‘å¤©åŽçš„æ—¥æœŸ
export const getDaysAfterDate = (date, days) => {
    if (days === 0) {
        return '2099-01-01'
    }
    const now = new Date(date);
    now.setDate(now.getDate() + days);
    const year = now.getFullYear();
    const month = now.getMonth() + 1; // æœˆä»½æ˜¯ä»Ž0开始的
    const day = now.getDate();
    return `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`;
}
// meeting
/**
 * èŽ·å–å½“å¤©æ—¥æœŸ
 **/
export const getDay = () => {
    let date = new Date();
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var day = date.getDate();
    month = (month > 9) ? month : ("0" + month);
    day = (day < 10) ? ("0" + day) : day;
    let week = '星期' + '日一二三四五六'.charAt(new Date().getDay())
    var today = year + "å¹´" + month + "月" + day + "日" + " " + week;
    return {
        today,
        date: year + "-" + month + "-" + day,
        day
    };
}
/**
 * èŽ·å–ä¸Šä¸€å¤©æ—¥æœŸ
 **/
export const getPreviousDay = (number, val) => {
    let num = (24*60*60*1000) * number;
    let date = ''
    if (val) {
        date = new Date(new Date(val).getTime() - num);
    } else {
        date = new Date(new Date().getTime() - num);
    }
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var day = date.getDate();
    month = (month > 9) ? month : ("0" + month);
    day = (day < 10) ? ("0" + day) : day;
    let week = '星期' + '日一二三四五六'.charAt(date.getDay())
    var today = year + "å¹´" + month + "月" + day + "日" + " " + week;
    return {
        today,
        date: year + "-" + month + "-" + day
    };
}
// æ ¼å¼åŒ–日对象
export const getNowDate = () => {
  var date = new Date();
  var sign2 = ":";
  var year = date.getFullYear() // å¹´
  var month = date.getMonth() + 1; // æœˆ
  var day = date.getDate(); // æ—¥
  var hour = date.getHours(); // æ—¶
  var minutes = date.getMinutes(); // åˆ†
  var seconds = date.getSeconds() //秒
  var weekArr = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期天'];
  var week = weekArr[date.getDay()];
  // ç»™ä¸€ä½æ•°çš„æ•°æ®å‰é¢åŠ  â€œ0”
  if (month >= 1 && month <= 9) {
    month = "0" + month;
  }
  if (day >= 0 && day <= 9) {
    day = "0" + day;
  }
  if (hour >= 0 && hour <= 9) {
    hour = "0" + hour;
  }
  if (minutes >= 0 && minutes <= 9) {
    minutes = "0" + minutes;
  }
  if (seconds >= 0 && seconds <= 9) {
    seconds = "0" + seconds;
  }
  return year + "-" + month + "-" + day + " " + hour + sign2 + minutes + sign2 + seconds;
}
//必须为字母加数字且长度不小于8位
export const CheckPassWord = (password) => {
   var str = password;
    if (str == null || str.length <8) {
        return false;
    }
    var reg1 = new RegExp(/^[0-9A-Za-z]+$/);
    if (!reg1.test(str)) {
        return false;
    }
    var reg = new RegExp(/[A-Za-z].*[0-9]|[0-9].*[A-Za-z]/);
    if (reg.test(str)) {
        return true;
    } else {
        return false;
    }
}