Merge branch 'miniprogram' into backend
This commit is contained in:
		
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README.md
									
									
									
									
									
								
							@@ -283,7 +283,7 @@ cd ../
 | 
			
		||||
 | 
			
		||||
##### 配置业务域名
 | 
			
		||||
 | 
			
		||||
修改 `miniprogram/src/app.js` 文件
 | 
			
		||||
1.修改 `miniprogram/src/app.js` 文件
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
App.use(setGlobalDataPlugin, {
 | 
			
		||||
@@ -293,7 +293,13 @@ App.use(setGlobalDataPlugin, {
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
同时记得在小程序后台填写小程序的业务域名。
 | 
			
		||||
2.配置服务域名
 | 
			
		||||
 | 
			
		||||
- 小程序:在[微信小程序后台](https://mp.weixin.qq.com/) - 左侧最下方**开发** - **开发管理** - 右侧上方**开发设置** - **服务器域名** 添加 `https://` 开头的**request合法域名**
 | 
			
		||||
- 小程序测试号:在[微信小程序后台](https://mp.weixin.qq.com/) - **服务器域名** 添加 `https://` 开头的**request合法域名**(注意不是业务域名)
 | 
			
		||||
- 支付宝沙箱应用:在[支付宝开放平台](https://open.alipay.com/develop/sandbox/app) - 左侧**沙箱应用** - **服务端域名白名单** 添加 `https://` 开头的**httpRequest接口请求域名白名单**
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##### 配置微信小程序appid
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,23 @@
 | 
			
		||||
const sleepTime = 0; // 模拟弱网环境等待时间
 | 
			
		||||
 | 
			
		||||
// 1. 导入http模块
 | 
			
		||||
const http = require("http");
 | 
			
		||||
var url = require("url");
 | 
			
		||||
 | 
			
		||||
// 2. 创建一个web服务器对象
 | 
			
		||||
const server = http.createServer();
 | 
			
		||||
 | 
			
		||||
// 3. 监听请求事件
 | 
			
		||||
server.on("request", (req, res) => {
 | 
			
		||||
    console.log(new Date(), "req.url", req.url);
 | 
			
		||||
 | 
			
		||||
server.on("request", async (req, res) => {
 | 
			
		||||
    //req-->request 请求对象, res-->response 响应对象
 | 
			
		||||
    // 通过响应头设置返回前台数据格式及编码。(解决中文乱码的问题)
 | 
			
		||||
    // res.setHeader('Content-Type', 'text/html;charset=utf-8');
 | 
			
		||||
    //res.write()表示向客户端输出的方法
 | 
			
		||||
    // res.write("hello world,你好nodejs")
 | 
			
		||||
 | 
			
		||||
    let urlObj = url.parse(req.url, true);
 | 
			
		||||
    let query = urlObj.query;
 | 
			
		||||
 | 
			
		||||
    res.setHeader('Content-Type', 'text/json;charset=utf-8');
 | 
			
		||||
 | 
			
		||||
    let result = {};
 | 
			
		||||
@@ -39,12 +43,32 @@ server.on("request", (req, res) => {
 | 
			
		||||
            // msg: "用户名或密码不正确",
 | 
			
		||||
            // data: null
 | 
			
		||||
        };
 | 
			
		||||
    } else if (req.url.startsWith('/access/getCodeInfo')) {
 | 
			
		||||
        result = {
 | 
			
		||||
            success: true,
 | 
			
		||||
            msg: "成功",
 | 
			
		||||
            data: {
 | 
			
		||||
                id: query.id,
 | 
			
		||||
                qrcodeColor: "green",
 | 
			
		||||
                infoText: "绿码 请通行",
 | 
			
		||||
                infoTextColor: "green",
 | 
			
		||||
                // qrcodeColor: "red",
 | 
			
		||||
                // infoText: "红码 禁止通行",
 | 
			
		||||
                // infoTextColor: "red",
 | 
			
		||||
            }
 | 
			
		||||
            // success: false,
 | 
			
		||||
            // msg: "用户名或密码不正确",
 | 
			
		||||
            // data: null
 | 
			
		||||
        };
 | 
			
		||||
    } else {
 | 
			
		||||
        result = {
 | 
			
		||||
            code: 500,
 | 
			
		||||
            success: false,
 | 
			
		||||
            msg: "服务器内部错误",
 | 
			
		||||
            data: null,
 | 
			
		||||
            extra: {
 | 
			
		||||
                url: req.url,
 | 
			
		||||
                query: query,
 | 
			
		||||
                urlObj: urlObj,
 | 
			
		||||
                method: req.method,
 | 
			
		||||
                headers: req.headers,
 | 
			
		||||
                req: Object.keys(req),
 | 
			
		||||
@@ -54,8 +78,14 @@ server.on("request", (req, res) => {
 | 
			
		||||
    }
 | 
			
		||||
    res.write(JSON.stringify(result));
 | 
			
		||||
 | 
			
		||||
    // 模拟弱网等待时间
 | 
			
		||||
    await new Promise((resolve) => {
 | 
			
		||||
        setTimeout(resolve, sleepTime);
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    //res.end()每次响应完,需要调用此方法 来结束响束
 | 
			
		||||
    res.end();
 | 
			
		||||
    console.log(new Date(), "req.url", req.url);
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// 4. 监听端口,为了避免端口冲突,这里给一个本机端口
 | 
			
		||||
@@ -64,4 +94,5 @@ server.listen(80, () => {
 | 
			
		||||
    console.log(`服务启动成功: ${baseUrl}/`);
 | 
			
		||||
    console.log();
 | 
			
		||||
    console.log(`${baseUrl}/user/login`);
 | 
			
		||||
    console.log(`${baseUrl}/access/getCodeInfo`);
 | 
			
		||||
}) 
 | 
			
		||||
 
 | 
			
		||||
@@ -8,12 +8,13 @@ const config = {
 | 
			
		||||
    828: 1.81 / 2
 | 
			
		||||
  },
 | 
			
		||||
  sourceRoot: 'src',
 | 
			
		||||
  outputRoot: 'dist',
 | 
			
		||||
  outputRoot: `dist/${process.env.TARO_ENV}`,
 | 
			
		||||
  plugins: [],
 | 
			
		||||
  defineConstants: {
 | 
			
		||||
  },
 | 
			
		||||
  copy: {
 | 
			
		||||
    patterns: [
 | 
			
		||||
      { from: 'src/image/', to: `dist/${process.env.TARO_ENV}/image/`, ignore: ['*.js'] }, // 指定需要 copy 的目录
 | 
			
		||||
    ],
 | 
			
		||||
    options: {
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
  "enableAppxNg": true,
 | 
			
		||||
  "enableNodeModuleBabelTransform": false,
 | 
			
		||||
  "enableNodeModuleBabelTransform": true,
 | 
			
		||||
  "miniprogramRoot": "./"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
    "miniprogramRoot": "dist/",
 | 
			
		||||
    "miniprogramRoot": "dist/weapp/",
 | 
			
		||||
    "projectname": "epp",
 | 
			
		||||
    "description": "基于微服务的社区疫情防控系统",
 | 
			
		||||
    "appid": "wxa70348746d2b562f",
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
    },
 | 
			
		||||
    "compileType": "miniprogram",
 | 
			
		||||
    "libVersion": "2.27.1",
 | 
			
		||||
    "srcMiniprogramRoot": "dist/",
 | 
			
		||||
    "srcMiniprogramRoot": "dist/weapp/",
 | 
			
		||||
    "packOptions": {
 | 
			
		||||
        "ignore": [],
 | 
			
		||||
        "include": []
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ export default defineAppConfig({
 | 
			
		||||
     * 用户侧
 | 
			
		||||
     */
 | 
			
		||||
    'pages/residents/code', // 进出码
 | 
			
		||||
    'pages/residents/report', // 体温上报
 | 
			
		||||
  ],
 | 
			
		||||
  window: {
 | 
			
		||||
    backgroundTextStyle: 'dark',
 | 
			
		||||
@@ -29,25 +30,33 @@ export default defineAppConfig({
 | 
			
		||||
        "iconPath": "image/icon/_code.png",
 | 
			
		||||
        "selectedIconPath": "image/icon/code.png"
 | 
			
		||||
      },
 | 
			
		||||
      // {
 | 
			
		||||
      //   "pagePath": "pages/report/report",
 | 
			
		||||
      //   "text": "日报",
 | 
			
		||||
      //   "iconPath": "/icon/_report.png",
 | 
			
		||||
      //   "selectedIconPath": "/icon/report.png"
 | 
			
		||||
      // },
 | 
			
		||||
      {
 | 
			
		||||
        "pagePath": "pages/residents/report",
 | 
			
		||||
        "text": "体温上报",
 | 
			
		||||
        "iconPath": "image/icon/_report.png",
 | 
			
		||||
        "selectedIconPath": "image/icon/report.png"
 | 
			
		||||
      },
 | 
			
		||||
      // {
 | 
			
		||||
      //   "pagePath": "pages/apply/apply",
 | 
			
		||||
      //   "text": "申请",
 | 
			
		||||
      //   "iconPath": "/icon/_apply.png",
 | 
			
		||||
      //   "selectedIconPath": "/icon/apply.png"
 | 
			
		||||
      //   "iconPath": "image/icon/_apply.png",
 | 
			
		||||
      //   "selectedIconPath": "image/icon/apply.png"
 | 
			
		||||
      // },
 | 
			
		||||
      // {
 | 
			
		||||
      //   "pagePath": "pages/person/person",
 | 
			
		||||
      //   "text": "我的",
 | 
			
		||||
      //   "selectedColor": "#FF8966",
 | 
			
		||||
      //   "iconPath": "/icon/_person.png",
 | 
			
		||||
      //   "selectedIconPath": "/icon/person.png"
 | 
			
		||||
      //   "iconPath": "image/icon/_person.png",
 | 
			
		||||
      //   "selectedIconPath": "image/icon/person.png"
 | 
			
		||||
      // }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  "permission": {
 | 
			
		||||
    "scope.userLocation": {
 | 
			
		||||
      "desc": "你的位置信息将用于体温上报"
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "requiredPrivateInfos": [
 | 
			
		||||
    "chooseLocation"
 | 
			
		||||
  ]
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,15 @@
 | 
			
		||||
/* 右上角小红点 */
 | 
			
		||||
.add-dot {
 | 
			
		||||
  position: relative;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.add-dot::after {
 | 
			
		||||
  content: " ";
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  right: -8rpx;
 | 
			
		||||
  top: -3rpx;
 | 
			
		||||
  width: 12rpx;
 | 
			
		||||
  height: 12rpx;
 | 
			
		||||
  background-color: red;
 | 
			
		||||
  border-radius: 50%;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ App.use(setGlobalDataPlugin, {
 | 
			
		||||
  globalData: {
 | 
			
		||||
    debugMode: true, // 是否展示调试内容
 | 
			
		||||
    baseUrl: true
 | 
			
		||||
      ? "http://39.99.244.156:5203"
 | 
			
		||||
      ? "https://epp.only4.work"
 | 
			
		||||
      : "http://localhost", // 不带最后的 /
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,11 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <view v-if="debugMode">
 | 
			
		||||
    <button @tap='debugCleanCache'>清除缓存</button>
 | 
			
		||||
    <textarea maxlength="-1" disabled="true" auto-height="true" :value="debugText"></textarea>
 | 
			
		||||
    <button type="warn" size="mini" @tap='debugCleanCache'>清除缓存</button>
 | 
			
		||||
    <view style="border: 3px solid black;">
 | 
			
		||||
      <input v-model="userRole" style="border: 1px solid grey; display: inline-block; width: 40%;" />
 | 
			
		||||
      <button style="width: 50%;" type="primary" size="mini" @tap='updateUserRole'>更新role ({{ userGroup }})</button>
 | 
			
		||||
    </view>
 | 
			
		||||
    <textarea maxlength="-1" disabled="true" auto-height="true" style="width: 100%" :value="debugText"></textarea>
 | 
			
		||||
  </view>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
@@ -9,25 +13,39 @@
 | 
			
		||||
import Taro from '@tarojs/taro'
 | 
			
		||||
import { eventCenter, getCurrentInstance } from '@tarojs/taro'
 | 
			
		||||
 | 
			
		||||
import ENUM from '../utils/const'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      userInfo: null,
 | 
			
		||||
      userRole: -1,
 | 
			
		||||
      debugMode: Taro.getApp().globalData.debugMode,
 | 
			
		||||
      debugText: "",
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    params: Object,
 | 
			
		||||
    userGroup: String
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    eventCenter.once(getCurrentInstance().router.onShow, () => {
 | 
			
		||||
      this.userInfo = Taro.getStorageSync("userInfo");
 | 
			
		||||
      this.displayUsername = this.userInfo?.username ?? "请登录";
 | 
			
		||||
      this.userRole = Taro.getStorageSync("userInfo").role;
 | 
			
		||||
 | 
			
		||||
      const res = Taro.getStorageInfoSync()
 | 
			
		||||
      let storage = {};
 | 
			
		||||
      res.keys.forEach(key => storage[key] = Taro.getStorageSync(key))
 | 
			
		||||
      this.debugText = JSON.stringify({
 | 
			
		||||
        "TARO_ENV": process.env.TARO_ENV,
 | 
			
		||||
        // "isVisitor": this.isVisitor,
 | 
			
		||||
        // "isUser": this.isUser,
 | 
			
		||||
        // "isAdmin": this.isAdmin,
 | 
			
		||||
        "userInfo": this.userInfo || 'null'
 | 
			
		||||
      }, null, 4)
 | 
			
		||||
        TARO_ENV: process.env.TARO_ENV,
 | 
			
		||||
        globalData: Taro.getApp().globalData,
 | 
			
		||||
        params: this.params,
 | 
			
		||||
        storage: storage,
 | 
			
		||||
        ENUM: ENUM,
 | 
			
		||||
        // storageInfo: {
 | 
			
		||||
        //   keys: res.keys,
 | 
			
		||||
        //   currentSize: res.currentSize,
 | 
			
		||||
        //   limitSize: res.limitSize
 | 
			
		||||
        // },
 | 
			
		||||
      }, null, 8)
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
@@ -43,6 +61,14 @@ export default {
 | 
			
		||||
          })
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    updateUserRole() {
 | 
			
		||||
      let userInfo = Taro.getStorageSync("userInfo");
 | 
			
		||||
      userInfo.role = this.userRole;
 | 
			
		||||
      Taro.setStorageSync("userInfo", userInfo);
 | 
			
		||||
      Taro.reLaunch({
 | 
			
		||||
        url: '/pages/index/index'
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 28 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 7.0 KiB  | 
@@ -1,3 +1,4 @@
 | 
			
		||||
export default definePageConfig({
 | 
			
		||||
  navigationBarTitleText: '首页'
 | 
			
		||||
  navigationBarTitleText: '首页',
 | 
			
		||||
  "navigationStyle": "custom"
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,15 @@
 | 
			
		||||
#menu-view {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  flex-wrap: wrap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.menu-item {
 | 
			
		||||
  width: 25%;
 | 
			
		||||
  margin-top: 50px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.item-image {
 | 
			
		||||
  width: 70px;
 | 
			
		||||
  height: 70px;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,130 +1,64 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <view>
 | 
			
		||||
    <image src="../../image/home.jpg" style="width: 100%;height: 145px;"></image>
 | 
			
		||||
    <image src="../../image/home.jpg" style="width: 100vw; height: 41.5vw;"></image>
 | 
			
		||||
    <view style="display: block; padding-left: 30px; padding-top: 12px;">
 | 
			
		||||
      <text>欢迎你,{{ displayUsername }}!</text>
 | 
			
		||||
    </view>
 | 
			
		||||
 | 
			
		||||
    <view style="display: block;" v-if="isVisitor">
 | 
			
		||||
      <view style="display: flex;text-align: center;margin-top: 20px;">
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/code.png" style="width: 40px;height: 40px;" @tap='goCode'></image>
 | 
			
		||||
          <view>进出码</view>
 | 
			
		||||
    <view id="menu-view">
 | 
			
		||||
      <view class="menu-item" v-for="menuItem in filterMenuItems" :key="menuItem.id">
 | 
			
		||||
        <view :class="{ 'add-dot': menuItem.addDot }" style="display: inline-block;">
 | 
			
		||||
          <image :src="'../../image/icon/' + menuItem.image" class="item-image"
 | 
			
		||||
            @tap='switchTo(menuItem.switchFunc, menuItem.url)'></image>
 | 
			
		||||
        </view>
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/feedback.png" style="width: 40px;height: 40px;" bindtap='goFeedback'></image>
 | 
			
		||||
          <view>反馈查看</view>
 | 
			
		||||
        </view>
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/apply.png" style="width: 40px;height: 40px;" bindtap='goApply'></image>
 | 
			
		||||
          <view>申请记录</view>
 | 
			
		||||
        <view>{{ menuItem.title }}</view>
 | 
			
		||||
      </view>
 | 
			
		||||
    </view>
 | 
			
		||||
    </view>
 | 
			
		||||
 | 
			
		||||
    <view style="display: block;" v-if="isUser">
 | 
			
		||||
      <view style="display: flex;text-align: center;margin-top: 20px;">
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/code.png" style="width: 40px;height: 40px;" @tap='goCode'></image>
 | 
			
		||||
          <view>进出码</view>
 | 
			
		||||
        </view>
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/feedback.png" style="width: 40px;height: 40px;" bindtap='goFeedback'></image>
 | 
			
		||||
          <view>反馈查看</view>
 | 
			
		||||
        </view>
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/apply.png" style="width: 40px;height: 40px;" bindtap='goApply'></image>
 | 
			
		||||
          <view>申请记录</view>
 | 
			
		||||
        </view>
 | 
			
		||||
      </view>
 | 
			
		||||
      <view style="display: flex;text-align: center;margin-top: 20px;">
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/yq.png" style="width: 40px;height: 40px;" data-web="xgPage" bindtap='goWebPage'>
 | 
			
		||||
          </image>
 | 
			
		||||
          <view>疫情追踪</view>
 | 
			
		||||
        </view>
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/report.png" style="width: 40px;height: 40px;" bindtap='goReport'></image>
 | 
			
		||||
          <view>今日日报</view>
 | 
			
		||||
        </view>
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/updPwd.png" style="width: 40px;height: 40px;" bindtap='goUpdPwd'></image>
 | 
			
		||||
          <view>密码修改</view>
 | 
			
		||||
        </view>
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/fk.png" style="width: 40px;height: 40px;" bindtap='goKf'></image>
 | 
			
		||||
          <view>提交反馈</view>
 | 
			
		||||
        </view>
 | 
			
		||||
      </view>
 | 
			
		||||
    </view>
 | 
			
		||||
 | 
			
		||||
    <view style="display: block;" v-if="isAdmin">
 | 
			
		||||
      <view style="display: flex;text-align: center;margin-top: 20px;">
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/danger.png" style="width: 40px;height: 40px;" bindtap='goCode'></image>
 | 
			
		||||
          <view>不健康人员</view>
 | 
			
		||||
        </view>
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/feedback.png" style="width: 40px;height: 40px;" bindtap='goFeedbackReplay'>
 | 
			
		||||
          </image>
 | 
			
		||||
          <view>反馈回复</view>
 | 
			
		||||
        </view>
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/apply.png" style="width: 40px;height: 40px;" bindtap='goApplyReplay'></image>
 | 
			
		||||
          <view>申请审批</view>
 | 
			
		||||
        </view>
 | 
			
		||||
      </view>
 | 
			
		||||
      <view style="display: flex;text-align: center;margin-top: 20px;">
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/gg.png" style="width: 40px;height: 40px;" data-web="xgPage" bindtap='goNotice'>
 | 
			
		||||
          </image>
 | 
			
		||||
          <view>公告发布</view>
 | 
			
		||||
        </view>
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/visitor.png" style="width: 40px;height: 40px;" bindtap="goVisitor"></image>
 | 
			
		||||
          <view>访客审批</view>
 | 
			
		||||
        </view>
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/count.png" style="width: 40px;height: 40px;" bindtap='goCount'></image>
 | 
			
		||||
          <view>分配账号</view>
 | 
			
		||||
        </view>
 | 
			
		||||
        <view style="width: 25%;">
 | 
			
		||||
          <image src="../../image/icon/_report.png" style="width: 40px;height: 40px;" bindtap='toRedList'></image>
 | 
			
		||||
          <view>今日未填</view>
 | 
			
		||||
        </view>
 | 
			
		||||
      </view>
 | 
			
		||||
    </view>
 | 
			
		||||
    <DebugComp />
 | 
			
		||||
    <button type="primary" size="mini" @tap="toggleDot('code', true)">显示小红点</button>
 | 
			
		||||
    <button type="primary" size="mini" @tap="toggleDot('code', false)">隐藏小红点</button>
 | 
			
		||||
    <DebugComp :params="debugObject" :userGroup="userGroup" />
 | 
			
		||||
  </view>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Taro from '@tarojs/taro'
 | 
			
		||||
import { eventCenter, getCurrentInstance } from '@tarojs/taro'
 | 
			
		||||
import ENUM from '../../utils/const.js'
 | 
			
		||||
import DebugComp from '../../components/DebugComp.vue'
 | 
			
		||||
import getUserGroupByRole from '../../utils/getUserGroupByRole'
 | 
			
		||||
import menuItemDict from '../../utils/menuList'
 | 
			
		||||
 | 
			
		||||
import './index.css'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      userInfo: null,
 | 
			
		||||
      displayUsername: "",
 | 
			
		||||
      isVisitor: false,
 | 
			
		||||
      isUser: false,
 | 
			
		||||
      isAdmin: false,
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  components: {
 | 
			
		||||
    DebugComp
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    eventCenter.once(getCurrentInstance().router.onShow, () => {
 | 
			
		||||
      console.log('onShow')
 | 
			
		||||
      console.log("ENUM", ENUM)
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      ...Taro.getApp().globalData,
 | 
			
		||||
      userInfo: null,
 | 
			
		||||
      displayUsername: "",
 | 
			
		||||
      userGroup: "unknown",
 | 
			
		||||
      menuItemDict: menuItemDict,
 | 
			
		||||
      debugObject: {},
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    filterMenuItems() {
 | 
			
		||||
      return Object.values(this.menuItemDict)
 | 
			
		||||
        .filter((item) => item.for.indexOf(this.userGroup) != -1)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onLoad() {
 | 
			
		||||
    // 开发模式下自动跳转到指定页面,节省开发时间
 | 
			
		||||
    if (this.debugMode) {
 | 
			
		||||
      Taro.switchTab({ url: '/pages/residents/report' })
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onShow() {
 | 
			
		||||
    console.log('onShow')
 | 
			
		||||
    console.log("menuItemDict", menuItemDict)
 | 
			
		||||
    this.userInfo = Taro.getStorageSync("userInfo");
 | 
			
		||||
    this.displayUsername = this.userInfo?.username ?? "请登录";
 | 
			
		||||
    if (!this.userInfo) {
 | 
			
		||||
@@ -133,32 +67,31 @@ export default {
 | 
			
		||||
        url: '/pages/index/login'
 | 
			
		||||
      })
 | 
			
		||||
    } else {
 | 
			
		||||
        const role = ENUM.user.role;
 | 
			
		||||
        this.isVisitor = [
 | 
			
		||||
          role.VISITOR,
 | 
			
		||||
        ].includes(this.userInfo.role);
 | 
			
		||||
        this.isUser = [
 | 
			
		||||
          role.RESIDENTS_OWNER,
 | 
			
		||||
          role.RESIDENTS_MEMBER,
 | 
			
		||||
          role.RESIDENTS_TENENT,
 | 
			
		||||
        ].includes(this.userInfo.role);
 | 
			
		||||
        this.isAdmin = [
 | 
			
		||||
          role.ADMIN,
 | 
			
		||||
          role.STAFF,
 | 
			
		||||
        ].includes(this.userInfo.role);
 | 
			
		||||
        console.log(
 | 
			
		||||
          "isVisitor", this.isVisitor,
 | 
			
		||||
          "isUser", this.isUser,
 | 
			
		||||
          "isAdmin", this.isAdmin
 | 
			
		||||
        )
 | 
			
		||||
      this.userGroup = getUserGroupByRole(this.userInfo.role);
 | 
			
		||||
      this.debugObject = { userGroup: this.userGroup };
 | 
			
		||||
    }
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    switchTo(func, pageUrl) {
 | 
			
		||||
      switch (func) {
 | 
			
		||||
        case 'switchTab':
 | 
			
		||||
          Taro.switchTab({ url: pageUrl })
 | 
			
		||||
          break;
 | 
			
		||||
        case 'navigateTo':
 | 
			
		||||
          Taro.navigateTo({ url: pageUrl })
 | 
			
		||||
          break;
 | 
			
		||||
        default:
 | 
			
		||||
          console.log("切换页面失败", func, pageUrl)
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    goCode() {
 | 
			
		||||
      Taro.switchTab({
 | 
			
		||||
        url: '/pages/residents/code'
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    toggleDot(iconName, status = true) {
 | 
			
		||||
      this.menuItemDict[iconName].addDot = status;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.inputText {
 | 
			
		||||
  width: 95%;
 | 
			
		||||
  border-bottom: solid 1px;
 | 
			
		||||
  margin-bottom: 50px;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,7 @@ export default {
 | 
			
		||||
        })
 | 
			
		||||
      } else {
 | 
			
		||||
        let passwordHash = md5(this.password);
 | 
			
		||||
        Taro.showLoading({ title: '加载中' })
 | 
			
		||||
        Taro.request({
 | 
			
		||||
          url: `${this.baseUrl}/user/login`,
 | 
			
		||||
          method: "POST",
 | 
			
		||||
@@ -54,19 +55,15 @@ export default {
 | 
			
		||||
            password: passwordHash,
 | 
			
		||||
          },
 | 
			
		||||
          success: function (d) {
 | 
			
		||||
            Taro.hideLoading()
 | 
			
		||||
            let result = d.data;
 | 
			
		||||
            if (result.success) {
 | 
			
		||||
              // 登录成功
 | 
			
		||||
              Taro.setStorageSync("userInfo", result.data.userInfo);
 | 
			
		||||
              console.log("userInfo", Taro.getStorageSync("userInfo"))
 | 
			
		||||
              Taro.showToast({
 | 
			
		||||
                title: "登录成功",
 | 
			
		||||
                icon: 'success',
 | 
			
		||||
                success: function () {
 | 
			
		||||
              Taro.switchTab({
 | 
			
		||||
                url: '/pages/index/index'
 | 
			
		||||
              })
 | 
			
		||||
                }
 | 
			
		||||
              })
 | 
			
		||||
            } else {
 | 
			
		||||
              Taro.showToast({
 | 
			
		||||
                title: result.msg,
 | 
			
		||||
@@ -76,6 +73,7 @@ export default {
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          fail: function () {
 | 
			
		||||
            Taro.hideLoading()
 | 
			
		||||
            Taro.showToast({
 | 
			
		||||
              title: "请求失败",
 | 
			
		||||
              icon: 'error',
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,30 @@
 | 
			
		||||
.time-text {
 | 
			
		||||
#codeView {
 | 
			
		||||
  text-align: center;
 | 
			
		||||
  margin-top: 100px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#user-text {
 | 
			
		||||
  font-size: 35px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#time-text {
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  font-size: 40px;
 | 
			
		||||
  margin-top: 50px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#myQrcode {
 | 
			
		||||
  display: block;
 | 
			
		||||
  margin: 0 auto;
 | 
			
		||||
 | 
			
		||||
  margin-top: 50px;
 | 
			
		||||
  margin-bottom: 40px;
 | 
			
		||||
  margin: 30px auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#show-text {
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  font-size: 45px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#small-text {
 | 
			
		||||
  margin-top: 80px;
 | 
			
		||||
  color: grey;
 | 
			
		||||
  font-size: small;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,16 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <view>
 | 
			
		||||
    <view style="text-align: center; margin-top: 100px;">
 | 
			
		||||
      <view><text>{{ id }} | {{ name }}</text></view>
 | 
			
		||||
      <canvas type="2d" style="width: 70vw; height: 70vw;" id="myQrcode"></canvas>
 | 
			
		||||
      <view><text class="time-text">{{ time }}</text></view>
 | 
			
		||||
    </view>
 | 
			
		||||
  <view id="codeView" :style="{ display: isShow }">
 | 
			
		||||
    <view id="user-text"><text>{{ userText }}</text></view>
 | 
			
		||||
    <view id="time-text"><text>{{ time }}</text></view>
 | 
			
		||||
    <canvas type="2d" style="width: 250px; height: 250px;" id="myQrcode"></canvas>
 | 
			
		||||
    <view id="show-text"><text :style="{ color: showTextColor }">{{ showText }}</text></view>
 | 
			
		||||
    <view id="small-text"><text>下拉可刷新</text></view>
 | 
			
		||||
  </view>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Taro from '@tarojs/taro'
 | 
			
		||||
import { eventCenter, getCurrentInstance } from '@tarojs/taro'
 | 
			
		||||
import md5 from 'blueimp-md5'
 | 
			
		||||
import drawQrcode from '../../utils/qrcode/index'
 | 
			
		||||
import utils from '../../utils/utils'
 | 
			
		||||
 | 
			
		||||
@@ -22,33 +22,41 @@ export default {
 | 
			
		||||
      ...Taro.getApp().globalData,
 | 
			
		||||
      userInfo: null,
 | 
			
		||||
      timeInterval: null,
 | 
			
		||||
      id: '',
 | 
			
		||||
      name: '',
 | 
			
		||||
      isShow: 'none',
 | 
			
		||||
      userText: '',
 | 
			
		||||
      showText: '',
 | 
			
		||||
      showTextColor: '',
 | 
			
		||||
      time: '',
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  // 对应 onShow
 | 
			
		||||
  onShow() {
 | 
			
		||||
    console.log('onShow')
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
      Taro.startPullDownRefresh();
 | 
			
		||||
    }, 100)
 | 
			
		||||
    setTimeout(this.refershData, 100)
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  // 对应 onHide
 | 
			
		||||
  onHide() {
 | 
			
		||||
    console.log('onHide')
 | 
			
		||||
    clearInterval(this.timeInterval);
 | 
			
		||||
    this.isShow = 'none'
 | 
			
		||||
    this.time = ''
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  // 对应 onPullDownRefresh
 | 
			
		||||
  onPullDownRefresh() {
 | 
			
		||||
    console.log('onPullDownRefresh')
 | 
			
		||||
    this.$nextTick(() => {
 | 
			
		||||
      this.refershData(() => {
 | 
			
		||||
        Taro.stopPullDownRefresh();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    refershData(callback) {
 | 
			
		||||
      this.debugMode && console.log('this.refershData()')
 | 
			
		||||
      Taro.showNavigationBarLoading();
 | 
			
		||||
      clearInterval(this.timeInterval);
 | 
			
		||||
    this.id = ''
 | 
			
		||||
    this.name = ''
 | 
			
		||||
      this.isShow = 'none'
 | 
			
		||||
      this.time = ''
 | 
			
		||||
      this.userInfo = Taro.getStorageSync("userInfo");
 | 
			
		||||
      if (!this.userInfo) {
 | 
			
		||||
@@ -56,36 +64,95 @@ export default {
 | 
			
		||||
          url: '/pages/index/login'
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    this.id = this.userInfo.id
 | 
			
		||||
    this.name = this.userInfo.realname
 | 
			
		||||
    this.drawCode()
 | 
			
		||||
    Taro.stopPullDownRefresh();
 | 
			
		||||
    Taro.hideNavigationBarLoading();
 | 
			
		||||
      Taro.showLoading({ title: '加载中' })
 | 
			
		||||
      var that = this;
 | 
			
		||||
      Taro.request({
 | 
			
		||||
        url: `${this.baseUrl}/access/getCodeInfo`,
 | 
			
		||||
        method: "POST",
 | 
			
		||||
        header: {
 | 
			
		||||
          "Content-Type": "application/x-www-form-urlencoded" //用于post
 | 
			
		||||
        },
 | 
			
		||||
        data: {
 | 
			
		||||
          id: this.userInfo.id,
 | 
			
		||||
        },
 | 
			
		||||
        success: function (d) {
 | 
			
		||||
          that.debugMode && console.log("begin success")
 | 
			
		||||
          Taro.hideLoading()
 | 
			
		||||
          let result = d.data;
 | 
			
		||||
          if (result.success) {
 | 
			
		||||
            console.log("result.data", result.data);
 | 
			
		||||
            that.userText = `${that.userInfo.id} | ${that.userInfo.realname}`
 | 
			
		||||
            that.showText = result.data.infoText
 | 
			
		||||
            that.showTextColor = result.data.infoTextColor
 | 
			
		||||
            that.$nextTick(() => {
 | 
			
		||||
              let t = Date.now();
 | 
			
		||||
              let chksum = md5(JSON.stringify({ id: that.userInfo.id, t: t }));
 | 
			
		||||
              that.drawCode(`https://epp.cxyxiaomo.com/access/validCode?id=${that.userInfo.id}&t=${t}&chksum=${chksum}`, result.data.qrcodeColor)
 | 
			
		||||
            });
 | 
			
		||||
          } else {
 | 
			
		||||
            Taro.showToast({
 | 
			
		||||
              title: result.msg,
 | 
			
		||||
              icon: 'error',
 | 
			
		||||
              duration: 2000
 | 
			
		||||
            })
 | 
			
		||||
          }
 | 
			
		||||
          that.isShow = ''
 | 
			
		||||
          that.debugMode && console.log("end success")
 | 
			
		||||
        },
 | 
			
		||||
        fail: function () {
 | 
			
		||||
          that.debugMode && console.log("begin fail")
 | 
			
		||||
          Taro.hideLoading()
 | 
			
		||||
          Taro.showToast({
 | 
			
		||||
            title: "请求失败",
 | 
			
		||||
            icon: 'error',
 | 
			
		||||
            duration: 2000
 | 
			
		||||
          })
 | 
			
		||||
          that.debugMode && console.log("end fail")
 | 
			
		||||
        },
 | 
			
		||||
        complete: function () {
 | 
			
		||||
          that.debugMode && console.log("begin complete")
 | 
			
		||||
          if (typeof (callback) === "function")
 | 
			
		||||
            callback();
 | 
			
		||||
          Taro.hideNavigationBarLoading();
 | 
			
		||||
          that.debugMode && console.log("end complete")
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
  methods: {
 | 
			
		||||
    drawCode(text = 'https://www.baidu.com/', foreground = 'red') {
 | 
			
		||||
      const query = wx.createSelectorQuery()
 | 
			
		||||
      this.debugMode && console.log("drawCode was called.")
 | 
			
		||||
      var that = this;
 | 
			
		||||
      const query = Taro.createSelectorQuery()
 | 
			
		||||
      query.select('#myQrcode')
 | 
			
		||||
        .fields({
 | 
			
		||||
          node: true,
 | 
			
		||||
          size: true
 | 
			
		||||
        })
 | 
			
		||||
        .exec((res) => {
 | 
			
		||||
        .exec(async (res) => {
 | 
			
		||||
          that.debugMode && console.log("before drawQrcode")
 | 
			
		||||
          var canvas = res[0].node
 | 
			
		||||
 | 
			
		||||
          if (!canvas) {
 | 
			
		||||
            Taro.showToast({
 | 
			
		||||
              title: "canvas获取失败",
 | 
			
		||||
              icon: 'error',
 | 
			
		||||
              duration: 2000
 | 
			
		||||
            })
 | 
			
		||||
            return
 | 
			
		||||
          }
 | 
			
		||||
          that.debugMode && console.log("canvas:", canvas, "res:", res)
 | 
			
		||||
          // 调用方法drawQrcode生成二维码
 | 
			
		||||
          drawQrcode({
 | 
			
		||||
          await drawQrcode(Taro, {
 | 
			
		||||
            canvas: canvas,
 | 
			
		||||
            canvasId: 'myQrcode',
 | 
			
		||||
            width: 260,
 | 
			
		||||
            padding: 30,
 | 
			
		||||
            width: 150,
 | 
			
		||||
            padding: 0,
 | 
			
		||||
            background: '#ffffff',
 | 
			
		||||
            foreground: foreground,
 | 
			
		||||
            text: text,
 | 
			
		||||
          })
 | 
			
		||||
          that.debugMode && console.log("end drawQrcode")
 | 
			
		||||
 | 
			
		||||
          this.timeInterval = setInterval(this.updateTime, 1000);
 | 
			
		||||
          this.updateTime();
 | 
			
		||||
          this.timeInterval = setInterval(this.updateTime, 1000);
 | 
			
		||||
        })
 | 
			
		||||
    },
 | 
			
		||||
    updateTime() {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								miniprogram/src/pages/residents/report.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								miniprogram/src/pages/residents/report.config.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
export default definePageConfig({
 | 
			
		||||
  navigationBarTitleText: '体温上报',
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										179
									
								
								miniprogram/src/pages/residents/report.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								miniprogram/src/pages/residents/report.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
.form {
 | 
			
		||||
  padding: 20px 30px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.row {
 | 
			
		||||
  margin: 30px 0;
 | 
			
		||||
  border-bottom: 2px solid grey;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.rowItem {
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
 | 
			
		||||
  vertical-align: middle;
 | 
			
		||||
  height: 1.6rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.rowLeft {
 | 
			
		||||
  width: 30%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.rowRight {
 | 
			
		||||
  width: 70%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.rowRightElement {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.center {
 | 
			
		||||
  text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.controlBtn {
 | 
			
		||||
  width: 250px;
 | 
			
		||||
  margin: 0 30px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <view class="form">
 | 
			
		||||
 | 
			
		||||
    <view class="row">
 | 
			
		||||
      <view class="rowItem rowLeft center">
 | 
			
		||||
        <text>姓名</text>
 | 
			
		||||
      </view>
 | 
			
		||||
      <view class="rowItem rowRight center">
 | 
			
		||||
        <input class="rowRightElement" :value="formData.userRealname" disabled="true" />
 | 
			
		||||
      </view>
 | 
			
		||||
    </view>
 | 
			
		||||
 | 
			
		||||
    <view class="row">
 | 
			
		||||
      <view class="rowItem rowLeft center">
 | 
			
		||||
        <text>填报时间</text>
 | 
			
		||||
      </view>
 | 
			
		||||
      <view class="rowItem rowRight center">
 | 
			
		||||
        <input class="rowRightElement" :value="formData.time" disabled="true" />
 | 
			
		||||
      </view>
 | 
			
		||||
    </view>
 | 
			
		||||
 | 
			
		||||
    <view class="row">
 | 
			
		||||
      <view class="rowItem rowLeft center">
 | 
			
		||||
        <text>地址</text>
 | 
			
		||||
      </view>
 | 
			
		||||
      <view class="rowItem rowRight center" @tap="chooseLocation">
 | 
			
		||||
        <input class="rowRightElement" placeholder="点击获取当前位置" v-model="formData.address" disabled="true"
 | 
			
		||||
          maxlength="500" />
 | 
			
		||||
      </view>
 | 
			
		||||
    </view>
 | 
			
		||||
 | 
			
		||||
    <view class="row">
 | 
			
		||||
      <view class="rowItem rowLeft center">
 | 
			
		||||
        <text>今日体温</text>
 | 
			
		||||
      </view>
 | 
			
		||||
      <view class="rowItem rowRight center">
 | 
			
		||||
        <radio-group class="rowRightElement" @change="(e) => formData.temperature = e.detail.value">
 | 
			
		||||
          <radio value="0" checked="true" />正常 
 | 
			
		||||
          <radio value="1" />异常(≥37.3°)
 | 
			
		||||
        </radio-group>
 | 
			
		||||
      </view>
 | 
			
		||||
    </view>
 | 
			
		||||
 | 
			
		||||
    <view class="tips-area">
 | 
			
		||||
      <view class="tips" style="color: red;">
 | 
			
		||||
        * 本人承诺以上所填报的内容全部真实,并愿意承担相应责任。
 | 
			
		||||
      </view>
 | 
			
		||||
    </view>
 | 
			
		||||
 | 
			
		||||
    <view style="text-align: center;">
 | 
			
		||||
      <button class="controlBtn" size="mini" type="none" @tap="myreport">历史填报</button>
 | 
			
		||||
      <button class="controlBtn" size="mini" type="primary" @tap="report">提交</button>
 | 
			
		||||
    </view>
 | 
			
		||||
 | 
			
		||||
    <textarea v-if="this.debugMode" maxlength="-1" disabled="true" auto-height="true" style="width: 100%"
 | 
			
		||||
      :value="JSON.stringify(formData, null, 8)"></textarea>
 | 
			
		||||
  </view>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Taro from '@tarojs/taro'
 | 
			
		||||
import utils from '../../utils/utils'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      ...Taro.getApp().globalData,
 | 
			
		||||
      userInfo: null,
 | 
			
		||||
      timeInterval: null,
 | 
			
		||||
      formData: {
 | 
			
		||||
        userId: '',
 | 
			
		||||
        userRealname: '',
 | 
			
		||||
        address: '',
 | 
			
		||||
        time: '',
 | 
			
		||||
        timestamp: '',
 | 
			
		||||
        temperature: 0,
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onShow() {
 | 
			
		||||
    console.log('onShow')
 | 
			
		||||
    this.userInfo = Taro.getStorageSync("userInfo")
 | 
			
		||||
    this.formData.userId = this.userInfo.id
 | 
			
		||||
    this.formData.userRealname = this.userInfo.realname
 | 
			
		||||
    this.updateTime();
 | 
			
		||||
    this.timeInterval = setInterval(this.updateTime, 1000);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  onHide() {
 | 
			
		||||
    console.log('onHide')
 | 
			
		||||
    clearInterval(this.timeInterval)
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    updateTime() {
 | 
			
		||||
      this.formData.timestamp = Date.now();
 | 
			
		||||
      this.formData.time = utils.formatTime(new Date(this.formData.timestamp));
 | 
			
		||||
    },
 | 
			
		||||
    chooseLocation: async function () {
 | 
			
		||||
      Taro.showLoading({ title: '正在定位' })
 | 
			
		||||
      await new Promise((resolve) => {
 | 
			
		||||
        Taro.getSetting({
 | 
			
		||||
          success(res) {
 | 
			
		||||
            if (!res.authSetting['scope.userLocation']) {
 | 
			
		||||
              Taro.authorize({
 | 
			
		||||
                scope: 'scope.userLocationBackground',
 | 
			
		||||
                success() {
 | 
			
		||||
                  resolve();
 | 
			
		||||
                }
 | 
			
		||||
              })
 | 
			
		||||
            } else {
 | 
			
		||||
              resolve();
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      });
 | 
			
		||||
      var that = this;
 | 
			
		||||
      Taro.chooseLocation({
 | 
			
		||||
        success: function (res) {
 | 
			
		||||
          that.formData.address = res.address;
 | 
			
		||||
        },
 | 
			
		||||
        fail: function () {
 | 
			
		||||
          if (!that.formData.address) {
 | 
			
		||||
            Taro.showToast({
 | 
			
		||||
              title: "请获取当前位置",
 | 
			
		||||
              icon: 'error'
 | 
			
		||||
            })
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
      Taro.hideLoading()
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										29
									
								
								miniprogram/src/utils/getUserGroupByRole.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								miniprogram/src/utils/getUserGroupByRole.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
const ENUM = require('./const.js');
 | 
			
		||||
 | 
			
		||||
function getUserGroupByRole(userRole) {
 | 
			
		||||
  const role = ENUM.user.role;
 | 
			
		||||
  userRole = Number(userRole);
 | 
			
		||||
  let userGroupDict = {
 | 
			
		||||
    'visitor': [
 | 
			
		||||
      role.VISITOR,
 | 
			
		||||
    ].includes(userRole),
 | 
			
		||||
    'user': [
 | 
			
		||||
      role.RESIDENTS_OWNER,
 | 
			
		||||
      role.RESIDENTS_MEMBER,
 | 
			
		||||
      role.RESIDENTS_TENENT,
 | 
			
		||||
    ].includes(userRole),
 | 
			
		||||
    'admin': [
 | 
			
		||||
      role.ADMIN,
 | 
			
		||||
      role.STAFF,
 | 
			
		||||
    ].includes(userRole)
 | 
			
		||||
  }
 | 
			
		||||
  console.log("userGroupDict", userGroupDict, userRole, role)
 | 
			
		||||
  for (let userGroup of Object.keys(userGroupDict)) {
 | 
			
		||||
    if (userGroupDict[userGroup]) {
 | 
			
		||||
      return userGroup;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return 'unknown';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = getUserGroupByRole;
 | 
			
		||||
							
								
								
									
										104
									
								
								miniprogram/src/utils/menuList.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								miniprogram/src/utils/menuList.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
const switchTab = "switchTab";
 | 
			
		||||
const navigateTo = "navigateTo";
 | 
			
		||||
let id = 0;
 | 
			
		||||
 | 
			
		||||
let menuItemDict = {
 | 
			
		||||
  'login': {
 | 
			
		||||
    for: ['unknown'],
 | 
			
		||||
    title: "登录",
 | 
			
		||||
    image: "code.png",
 | 
			
		||||
    switchFunc: switchTab,
 | 
			
		||||
    url: '/pages/index/login',
 | 
			
		||||
  },
 | 
			
		||||
  'code': {
 | 
			
		||||
    for: ['visitor', 'user'],
 | 
			
		||||
    title: "进出码",
 | 
			
		||||
    image: "code.png",
 | 
			
		||||
    switchFunc: switchTab,
 | 
			
		||||
    url: '/pages/residents/code'
 | 
			
		||||
  },
 | 
			
		||||
  'report': {
 | 
			
		||||
    for: ['user'],
 | 
			
		||||
    title: "体温上报",
 | 
			
		||||
    image: "report.png",
 | 
			
		||||
    switchFunc: switchTab,
 | 
			
		||||
    url: '/pages/residents/report'
 | 
			
		||||
  },
 | 
			
		||||
  'apply-record': {
 | 
			
		||||
    for: ['visitor', 'user'],
 | 
			
		||||
    title: "申请记录",
 | 
			
		||||
    image: "apply.png",
 | 
			
		||||
    switchFunc: switchTab,
 | 
			
		||||
    url: ''
 | 
			
		||||
  },
 | 
			
		||||
  'apply-approval': {
 | 
			
		||||
    for: ['admin'],
 | 
			
		||||
    title: "申请审批",
 | 
			
		||||
    image: "apply.png", // ApplyReplay
 | 
			
		||||
    switchFunc: switchTab,
 | 
			
		||||
    url: ''
 | 
			
		||||
  },
 | 
			
		||||
  'visitor-apply': {
 | 
			
		||||
    for: ['admin'],
 | 
			
		||||
    title: "访客审批",
 | 
			
		||||
    image: "visitor.png",
 | 
			
		||||
    switchFunc: switchTab,
 | 
			
		||||
    url: ''
 | 
			
		||||
  },
 | 
			
		||||
  'abnormal': {
 | 
			
		||||
    for: ['admin'],
 | 
			
		||||
    title: "异常人员",
 | 
			
		||||
    image: "danger.png",
 | 
			
		||||
    switchFunc: switchTab,
 | 
			
		||||
    url: ''
 | 
			
		||||
  },
 | 
			
		||||
  'feedback-submit': {
 | 
			
		||||
    for: ['visitor', 'user'],
 | 
			
		||||
    title: "提交反馈",
 | 
			
		||||
    image: "fk.png",
 | 
			
		||||
    switchFunc: switchTab,
 | 
			
		||||
    url: ''
 | 
			
		||||
  },
 | 
			
		||||
  'feedback-list': {
 | 
			
		||||
    for: ['visitor', 'user'],
 | 
			
		||||
    title: "反馈查看",
 | 
			
		||||
    image: "feedback.png",
 | 
			
		||||
    switchFunc: switchTab,
 | 
			
		||||
    url: ''
 | 
			
		||||
  },
 | 
			
		||||
  'feedback-reply': {
 | 
			
		||||
    for: ['admin'],
 | 
			
		||||
    title: "反馈回复",
 | 
			
		||||
    image: "feedback.png",
 | 
			
		||||
    switchFunc: switchTab,
 | 
			
		||||
    url: ''
 | 
			
		||||
  },
 | 
			
		||||
  'update-password': {
 | 
			
		||||
    for: ['user', 'admin'],
 | 
			
		||||
    title: "密码修改",
 | 
			
		||||
    image: "updPwd.png",
 | 
			
		||||
    switchFunc: switchTab,
 | 
			
		||||
    url: ''
 | 
			
		||||
  },
 | 
			
		||||
  'assign': {
 | 
			
		||||
    for: ['admin'],
 | 
			
		||||
    title: "分配账号",
 | 
			
		||||
    image: "count.png",
 | 
			
		||||
    switchFunc: switchTab,
 | 
			
		||||
    url: ''
 | 
			
		||||
  },
 | 
			
		||||
  'unfinish': {
 | 
			
		||||
    for: ['admin'],
 | 
			
		||||
    title: "今日未填", // RedList
 | 
			
		||||
    image: "_report.png",
 | 
			
		||||
    switchFunc: switchTab,
 | 
			
		||||
    url: ''
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
let keys = Object.keys(menuItemDict);
 | 
			
		||||
for (let key of keys) {
 | 
			
		||||
  menuItemDict[key].id = id++;
 | 
			
		||||
  menuItemDict[key].addDot = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = menuItemDict
 | 
			
		||||
@@ -25,16 +25,15 @@ function utf16to8(str) {
 | 
			
		||||
  return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function drawQrcode(options, debug) {
 | 
			
		||||
function drawQrcode(Taro, options) {
 | 
			
		||||
  options = options || {}
 | 
			
		||||
  options = extend(true, {
 | 
			
		||||
    canvasId: 'myQrcode',
 | 
			
		||||
    // canvas: canvas,
 | 
			
		||||
    canvas: null,
 | 
			
		||||
    text: '爱一个人就要勇敢说出来',
 | 
			
		||||
    width: 260,
 | 
			
		||||
    height: 260,
 | 
			
		||||
    padding: 20,
 | 
			
		||||
    // paddingColor: '#ffffff', // 默认与background一致
 | 
			
		||||
    paddingColor: null, // 默认与background一致
 | 
			
		||||
    typeNumber: -1,
 | 
			
		||||
    correctLevel: QRErrorCorrectLevel.H,
 | 
			
		||||
    background: '#ffffff',
 | 
			
		||||
@@ -54,44 +53,29 @@ function drawQrcode(options, debug) {
 | 
			
		||||
 | 
			
		||||
  if (!options.paddingColor) options.paddingColor = options.background
 | 
			
		||||
 | 
			
		||||
  if (debug) {
 | 
			
		||||
    var qrcode = new QRCode(options.typeNumber, options.correctLevel)
 | 
			
		||||
    qrcode.addData(utf16to8(options.text))
 | 
			
		||||
    qrcode.make()
 | 
			
		||||
 | 
			
		||||
    return new Promise(function (resolve, reject) {
 | 
			
		||||
      resolve(qrcode);
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
  } else {
 | 
			
		||||
 | 
			
		||||
    return new Promise(function (resolve, reject) {
 | 
			
		||||
      return resolve(createCanvas());
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function createCanvas() {
 | 
			
		||||
  // createCanvas
 | 
			
		||||
  // create the qrcode itself
 | 
			
		||||
  var qrcode = new QRCode(options.typeNumber, options.correctLevel)
 | 
			
		||||
  qrcode.addData(utf16to8(options.text))
 | 
			
		||||
  qrcode.make()
 | 
			
		||||
 | 
			
		||||
    const dpr = wx ? wx.getSystemInfoSync().pixelRatio : 1 // 兼容支付宝小程序
 | 
			
		||||
  const dpr = Taro.getSystemInfoSync().pixelRatio
 | 
			
		||||
  var canvas = options.canvas
 | 
			
		||||
  const ctx = canvas.getContext('2d')
 | 
			
		||||
  canvas.width = options.width * dpr
 | 
			
		||||
  canvas.height = options.width * dpr
 | 
			
		||||
  const width = canvas.width
 | 
			
		||||
  console.log(`canvas, ctx, width, dpr, qrcode, options`, canvas, ctx, width, dpr, qrcode, options)
 | 
			
		||||
 | 
			
		||||
    // 背景色
 | 
			
		||||
  // 填充背景色
 | 
			
		||||
  ctx.fillStyle = options.paddingColor
 | 
			
		||||
  // ctx.clearRect(0, 0, width + options.padding * 2, width + options.padding * 2) // 绘制前清空画布
 | 
			
		||||
  ctx.fillRect(0, 0, width + options.padding * 2, width + options.padding * 2);
 | 
			
		||||
 | 
			
		||||
  var tileW = (width - options.padding * 2) / qrcode.getModuleCount()
 | 
			
		||||
  var tileH = (width - options.padding * 2) / qrcode.getModuleCount()
 | 
			
		||||
 | 
			
		||||
    // 开始画二维码
 | 
			
		||||
  // 绘制二维码
 | 
			
		||||
  for (var row = 0; row < qrcode.getModuleCount(); row++) {
 | 
			
		||||
    for (var col = 0; col < qrcode.getModuleCount(); col++) {
 | 
			
		||||
      ctx.fillStyle = qrcode.isDark(row, col) ? options.foreground : options.background
 | 
			
		||||
@@ -101,6 +85,7 @@ function drawQrcode(options, debug) {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 绘制中心图标
 | 
			
		||||
  if (options.image.imageResource) {
 | 
			
		||||
    const imgW = options.image.width * dpr
 | 
			
		||||
    const imgH = options.image.height * dpr
 | 
			
		||||
@@ -136,6 +121,5 @@ function drawQrcode(options, debug) {
 | 
			
		||||
 | 
			
		||||
  return ctx
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default drawQrcode
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user