Browse Source

(*) 小程序码实现

master
liujiangyong 2 years ago
parent
commit
ec97c14091
  1. 17
      api/.vscode/launch.json
  2. 67
      api/app/lib/controllers/projectRegime/projectSituation.js
  3. 23
      api/app/lib/middlewares/attachment.js
  4. 27
      api/config.js
  5. 1
      api/package.json
  6. 91
      weapp/package/startInspection/startInspection.js
  7. 22
      weapp/package/startInspection/startInspection.wxml
  8. 4
      weapp/package/startInspection/startInspection.wxss
  9. 18
      weapp/pages/login/login.js
  10. 138
      web/client/src/sections/projectRegime/containers/point.js
  11. 38
      web/client/src/sections/projectRegime/containers/qrCode.js

17
api/.vscode/launch.json

@ -15,18 +15,25 @@
"args": [
"-p 4900",
//
"-g postgres://postgres:123456@10.8.30.166:5432/XunJian",
"-g postgres://postgres:123456@10.8.16.184:5432/XunJian",
//
// "--apiEmisUrl http://10.8.30.161:1111",
"--qnak XuDgkao6cL0HidoMAPnA5OB10Mc_Ew08mpIfRJK5",
"--qnsk yewcieZLzKZuDfig0wLZ9if9jKp2P_1jd3CMJPSa",
"--qnbkt dev-hr",
// "--qnak XuDgkao6cL0HidoMAPnA5OB10Mc_Ew08mpIfRJK5",
// "--qnsk yewcieZLzKZuDfig0wLZ9if9jKp2P_1jd3CMJPSa",
// "--qnbkt dev-hr",
// "--qndmn http://resources.anxinyun.cn",
"--qndmn http://rjkwed13l.hn-bkt.clouddn.com",
// "--qndmn http://rjkwed13l.hn-bkt.clouddn.com",
"--qnak 5XrM4wEB9YU6RQwT64sPzzE6cYFKZgssdP5Kj3uu",
"--qnsk w6j2ixR_i-aelc6I7S3HotKIX-ukMzcKmDfH6-M5",
"--qnbkt anxinyun-test",
"--qndmn http://test.resources.anxinyun.cn",
"--aliOssAccessKey LTAI5tNDfn7UhStYQcn3JBtw",
"--aliOssSecretKey rnoXtDWQA1djJ5Xqcdn1OSEol0lVyv",
"--aliOssBucket test-c371",
"--aliOssRegion oss-cn-hangzhou",
"--wxDomain https://api.weixin.qq.com",
"--wxAppId wxdd82ae635b22ccdb",
"--wxAppSecret 08e3d4ea9484cd7837d171e7af7c7db8",
]
},
{

67
api/app/lib/controllers/projectRegime/projectSituation.js

@ -1,7 +1,9 @@
'use strict';
const request = require('superagent');
const fs = require('fs');
const path = require('path');
async function projectList (ctx, next) {
async function projectList(ctx, next) {
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
@ -48,7 +50,7 @@ async function projectList (ctx, next) {
}
async function postAddProject (ctx, next) {
async function postAddProject(ctx, next) {
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
@ -89,7 +91,7 @@ async function postAddProject (ctx, next) {
}
}
async function delProject (ctx, next) {
async function delProject(ctx, next) {
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
@ -152,12 +154,17 @@ async function delProject (ctx, next) {
}
}
async function addPosition (ctx, next) {
let wxAccessToken = {
access_token: null,
time: null
}
async function addPosition(ctx, next) {
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
const data = ctx.request.body;
const { longitude, latitude, name, describe, qrCode, projectId, } = data
const { longitude, latitude, name, describe, qrCode, projectId, } = data;
let errMsg = data.id ? '点位编辑失败' : '点位新增失败'
let pointData = { longitude, latitude, name, describe, qrCode, projectId }
@ -170,11 +177,44 @@ async function addPosition (ctx, next) {
if (data && data.id) {
if (qrCode) {
await models.Point.update({ ...alikeProject, qrCode }, {
const { domain, appId, appSecret } = ctx.app.fs.opts.wx;
// 获取小程序AccessToken, 两小时过期
if (!wxAccessToken.access_token || new Date().getTime() - wxAccessToken.time >= 7200000) {
const wxAccessTokenRes = await request.get(`${domain}/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${appSecret}`);
if (wxAccessTokenRes.body.access_token) {
wxAccessToken.access_token = wxAccessTokenRes.body.access_token;
wxAccessToken.time = new Date().getTime();
} else {
throw '请求微信AccessToken失败';
}
}
// 获取小程序码
const QRCodeRes = await request.post(
`${domain}/wxa/getwxacodeunlimit?access_token=${wxAccessToken.access_token}`,
{
"page": "package/startInspection/startInspection",
"scene": data.id
}
);
if (QRCodeRes.ok) {
const pathname = path.join(__dirname, `${alikeProject.name}.jpeg`);
// 写入临时文件
fs.writeFileSync(pathname, QRCodeRes.body, async function (err) {
if (err) {
throw err;
}
});
const fileInfo = await ctx.app.fs.attachment.upload(pathname, { uploadPath: 'project' });
fs.unlinkSync(pathname); // 删除临时文件
let fkey = fileInfo.key;
await models.Point.update({ ...alikeProject, qrCode: fkey }, {
where: {
id: data.id,
}
})
} else {
throw '生成二维码失败'
}
} else {
await models.Point.update({ pointData }, {
where: {
@ -187,18 +227,17 @@ async function addPosition (ctx, next) {
await models.Point.create(pointData)
}
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`)
ctx.status = 400;
ctx.body = {
"message": errMsg
message: error.message
}
}
}
async function position (ctx, next) {
async function position(ctx, next) {
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
@ -231,7 +270,7 @@ async function position (ctx, next) {
}
}
async function delPosition (ctx, next) {
async function delPosition(ctx, next) {
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
@ -279,7 +318,7 @@ async function delPosition (ctx, next) {
userId: u.dataValues.userId,
patrolCount: u.dataValues.patrolCount
}
await models.PatrolPlan.update(data,{
await models.PatrolPlan.update(data, {
where: {
id: u.dataValues.id
}
@ -313,7 +352,7 @@ async function delPosition (ctx, next) {
}
async function qrCodeShow (ctx, next) {
async function qrCodeShow(ctx, next) {
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
@ -344,7 +383,7 @@ async function qrCodeShow (ctx, next) {
}
async function q (ctx) {
async function q(ctx) {
// let error = {
// name: 'FindError',
// message: "获取失败!"

23
api/app/lib/middlewares/attachment.js

@ -0,0 +1,23 @@
/**
* Created by PengLing on 2018/1/2.
*/
'use strict';
const Attachment = require('fs-attachment');
module.exports = {
entry: function (app, router, opts) {
const attachment = new Attachment(opts);
app.fs = app.fs || {};
app.fs.attachment = attachment;
app.fs.logger.log('debug', 'init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)');
return async (ctx, next) => {
ctx.fs = ctx.fs || {};
ctx.fs.attachment = attachment;
await next();
};
}
};

27
api/config.js

@ -20,6 +20,9 @@ args.option('aliOssAccessKey', '阿里OSS AccessKey');
args.option('aliOssSecretKey', '阿里OSS SecretKey');
args.option('aliOssBucket', '阿里OSS Bucket');
args.option('aliOssRegion', '阿里OSS Region');
args.option('wxDomain', '微信API Domain');
args.option('wxAppId', '微信小程序appid');
args.option('wxAppSecret', '微信小程序AppSecret');
const flags = args.parse(process.argv);
@ -37,8 +40,13 @@ const ALI_OSS_SECRETKET = process.env.ALI_OSS_SECRETKET || flags.aliOssSecretKey
const ALI_OSS_BUCKET = process.env.ALI_OSS_BUCKET || flags.aliOssBucket;
const ALI_OSS_REGION = process.env.ALI_OSS_REGION || flags.aliOssRegion;
// 微信小程序参数
const WX_DOMAIN = process.env.WX_DOMAIN || flags.wxDomain;
const WX_APP_ID = process.env.WX_APP_ID || flags.wxAppId;
const WX_APP_SECRET = process.env.WX_APP_SECRET || flags.wxAppSecret;
if (!XUNJIAN_DB || !QINIU_DOMAIN_QNDMN_RESOURCE || !QINIU_BUCKET_RESOURCE || !QINIU_AK || !QINIU_SK) {
if (!XUNJIAN_DB || !QINIU_DOMAIN_QNDMN_RESOURCE || !QINIU_BUCKET_RESOURCE || !QINIU_AK || !QINIU_SK || !WX_DOMAIN || !WX_APP_ID || !WX_APP_SECRET) {
console.log('缺少启动参数,异常退出');
args.showHelp();
process.exit(-1);
@ -59,6 +67,18 @@ const product = {
},
maxSize: 104857600, // 100M
}
}, {
entry: require('./app/lib/middlewares/attachment').entry,
opts: {
qiniu: {
accessKey: QINIU_AK,
secretKey: QINIU_SK,
bucket: QINIU_BUCKET_RESOURCE,
domain: QINIU_DOMAIN_QNDMN_RESOURCE
},
maxSize: 104857600, // 100M
// uploadPath: 'other'
}
}, {
entry: require('./app').entry,
opts: {
@ -93,6 +113,11 @@ const product = {
password: 'Fs2689'
}
},
wx: {
domain: WX_DOMAIN,
appId: WX_APP_ID,
appSecret: WX_APP_SECRET
}
}
}
],

1
api/package.json

@ -21,6 +21,7 @@
"clickhouse": "^2.6.0",
"crypto-js": "^4.0.0",
"file-saver": "^2.0.2",
"fs-attachment": "^1.0.0",
"fs-web-server-scaffold": "^2.0.2",
"ioredis": "^5.0.4",
"kafka-node": "^2.2.3",

91
weapp/package/startInspection/startInspection.js

@ -1,6 +1,12 @@
// package/startInspection/startInspection.js
import { addPatrolRecord, getPatrolRecord } from "../../utils/getApiUrl";
import { Request } from "../../common";
// package/startInspectiocurPlann/startInspection.js
import {
addPatrolRecord,
getPatrolRecord,
getPatrolPlan
} from "../../utils/getApiUrl";
import {
Request
} from "../../common";
const moment = require("../../utils/moment");
Page({
@ -9,6 +15,9 @@ Page({
* 页面的初始数据
*/
data: {
scenePointId: null,
planList: null,
index: null,
dataList: '',
imgs: [], //上传图片
imgUrl: getApp().globalData.imgUrl,
@ -19,6 +28,23 @@ Page({
address: '', //当前位置
},
bindPickerChange: function (e) {
this.setData({
index: e.detail.value
})
const curPlan = this.data.planList[e.detail.value];
let points = curPlan.points.map(e => {
return e.name
}).join('、')
this.setData({
dataList: curPlan,
points,
showModal: true,
itemData: curPlan.points.find(p => p.id == this.data.scenePointId)
})
this.getPatrolRecord();
},
handleChangeTwo(e) {
this.setData({
changeTwo: e.detail.value
@ -137,7 +163,7 @@ Page({
data.i = i;
data.success = success;
data.fail = fail;
that.uploadimg(data);//递归,回调自己
that.uploadimg(data); //递归,回调自己
}
}
});
@ -176,7 +202,16 @@ Page({
// 开始巡检录入
addPatrolRecord: function () {
let that = this;
let { itemData, imgs, msgInp, changeTwo, changeThree, dataList, imgUrl, address } = that.data;
let {
itemData,
imgs,
msgInp,
changeTwo,
changeThree,
dataList,
imgUrl,
address
} = that.data;
let newImgs = imgs.map(i => {
i = i.replace(imgUrl, '');
return i;
@ -302,7 +337,7 @@ Page({
return "";
}
var i = val.indexOf('.');
var strDu = i < 0 ? val : val.substring(0, i);//获取度
var strDu = i < 0 ? val : val.substring(0, i); //获取度
var strFen = 0;
var strMiao = 0;
if (i > 0) {
@ -311,11 +346,11 @@ Page({
i = strFen.indexOf('.');
if (i > 0) {
strMiao = "0" + strFen.substring(i);
strFen = strFen.substring(0, i);//获取分
strFen = strFen.substring(0, i); //获取分
strMiao = strMiao * 60 + "";
i = strMiao.indexOf('.');
strMiao = strMiao.substring(0, i + 4);//取到小数点后面三位
strMiao = parseFloat(strMiao).toFixed(2);//精确小数点后面两位
strMiao = strMiao.substring(0, i + 4); //取到小数点后面三位
strMiao = parseFloat(strMiao).toFixed(2); //精确小数点后面两位
}
}
return strDu + "°" + strFen + "′" + strMiao + "″";
@ -354,11 +389,48 @@ Page({
});
},
// 获取巡检计划
getPatrolPlan: function (scenePointId) {
let that = this;
wx.showLoading({
title: '加载中',
})
Request.get(getPatrolPlan(), {}).then(res => {
wx.hideLoading();
const pointPlan = res.rows.filter(plan => {
for (const point of plan.points) {
if (point.id == scenePointId) {
return true;
}
}
return false;
})
that.setData({
planList: pointPlan
})
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
let that = this;
const scenePointId = options.scene;
if (scenePointId) { // 扫小程序码进入
const userInfo = wx.getStorageSync('userInfo');
if (!userInfo || !userInfo.id) { // 如果没登录,先登录
wx.showToast({ title: '请先登录' })
wx.reLaunch({
url: `/pages/login/login?scene=${scenePointId}`
});
return;
}
that.setData({
scenePointId
})
that.getPatrolPlan(scenePointId);
} else { // 正常点击进入
let data = JSON.parse(decodeURIComponent(options.data));
let points = data.points.map(e => {
return e.name
@ -368,6 +440,7 @@ Page({
points
})
that.getPatrolRecord();
}
},
/**

22
weapp/package/startInspection/startInspection.wxml

@ -1,5 +1,13 @@
<!--package/startInspection/startInspection.wxml-->
<!-- package/startInspection/startInspection.wxml -->
<view class="box">
<view wx:if="{{planList}}">
<picker bindchange="bindPickerChange" value="{{index}}" range="{{planList}}" range-key="name">
<view class="picker" style="{{index===null ? 'color:red' : 'color:black'}}">
{{index===null ? '请选择巡检计划:' : '巡检计划:'}}{{planList[index].name}}
</view>
</picker>
<view class="line"></view>
</view>
<view class="titleFirst">巡检要求</view>
<view class="txt">
<view style="float: left;font-weight: bold;">结构物名称</view>
@ -56,7 +64,6 @@
</view>
</view>
</block>
<!-- 开始巡检弹框 -->
<view class="modal" wx:if="{{showModal}}">
<view class="popBox">
@ -66,8 +73,12 @@
</view>
<view style="padding:20rpx 30rpx;overflow: hidden;">
<view style="float: left;">当前位置:</view>
<view style="float:left;width:480rpx;text-align: justify;" wx:if="{{address}}">{{address}}</view>
<view style="float:left;width:480rpx;text-align: justify;" bindtap="selfLocation" wx:if="{{!address}}">点击获取当前位置</view>
<view style="float:left;width:480rpx;text-align: justify;" wx:if="{{address}}">
{{address}}
</view>
<view style="float:left;width:480rpx;text-align: justify;" bindtap="selfLocation" wx:if="{{!address}}">
点击获取当前位置
</view>
</view>
<radio-group style="padding:10px 15px;display:flex;justify-content: space-evenly;" bindchange="handleChangeTwo">
<radio style="color:#1979ff;" color="#1979ff" value="normal">正常</radio>
@ -79,7 +90,6 @@
<radio style="color:#FF3300;" color="#FF3300" value="moderate">中度</radio>
<radio style="color:#990000;" color="#990000" value="severity">严重</radio>
</radio-group>
<view class="weui-uploader" style="padding: 20rpx 30rpx;height:350rpx;overflow-y:scroll;" wx:if="{{changeTwo == 'abnormal'}}">
<view class="img-v weui-uploader__bd" style="overflow:hidden;">
<view class='pic' wx:for="{{imgs}}" wx:for-item="item" wx:key="*this">
@ -93,12 +103,10 @@
</view>
</view>
</view>
<view class="btnBox">
<view class="cancel" bindtap="bindCancel">取消</view>
<view class="submit" bindtap="addPatrolRecord">提交</view>
</view>
</view>
</view>
</view>

4
weapp/package/startInspection/startInspection.wxss

@ -5,6 +5,10 @@
padding: 30rpx 0;
}
.picker {
margin-bottom: 40rpx;
}
.titleFirst {
font-size: 32rpx;
margin-bottom: 30rpx;

18
weapp/pages/login/login.js

@ -8,7 +8,7 @@ Page({
* 页面的初始数据
*/
data: {
scene: null,
},
// 登录
@ -32,10 +32,16 @@ Page({
wx.setStorageSync('token', res.token);
wx.setStorageSync("userInfo", res);
getApp().globalData.userInfo = res
wx.hideLoading()
if (this.data.scene) {
wx.redirectTo({
url: `/package/startInspection/startInspection?scene=${this.data.scene}`,
})
return;
}
wx.switchTab({
url: '/pages/index/index',
})
wx.hideLoading()
})
},
@ -66,7 +72,13 @@ Page({
* 生命周期函数--监听页面加载
*/
onLoad(options) {
let that = this;
const { scene } = options;
if (scene) {
that.setData({
scene
})
}
},
/**

138
web/client/src/sections/projectRegime/containers/point.js

@ -1,34 +1,22 @@
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { Spin, Card, Form, Input, Select, Button, Table, Modal, Popconfirm, Tooltip } from 'antd';
const { TextArea } = Input;
import moment from "moment";
import { Button, Table, Popconfirm } from 'antd';
import '../style.less';
import { push } from 'react-router-redux';
import PointModel from '../components/pointModel'
import { Model } from 'qrcode';
const Information = (props) => {
const { dispatch, actions, user, loading } = props
const { dispatch, actions } = props
const { projectRegime } = actions
const [firmList, setFirmList] = useState([])
const [tableList, settableList] = useState([])
const [addModel, setAddModel] = useState(false)
const [modelData, setModelData] = useState({})
const [query, setQuery] = useState({ limit: 10, page: 0 })
const [limits, setLimits] = useState()
const [search, setSearch] = useState({})
const [isPicture, setIsPicture] = useState(false)
const [pictureUrl, setPictureUrl] = useState()
const [companyID, setCompanyId] = useState('')
const [select, setSelect] = useState([])
const [selec, setSelec] = useState()
const [form] = Form.useForm();
var QRCode = require('qrcode')
const { createCanvas, loadImage, registerFont } = require('canvas')
const [qrCodeingIds, setQrCodeingIds] = useState(null)
const qrCodeId = props?.match?.params?.id
@ -53,77 +41,7 @@ const Information = (props) => {
})
}
const createQrCode = (name) => {
let url = ''
QRCode.toDataURL(name, {
errorCorrectionLevel: 'low',
type: 'image/png',
quality: 0.3,
margin: 2,
maskPattern: 9,
width: 400,
color: {
dark: "#000000ff",
light: "#ffffffff"
}
}, function (err, v) {
url = v
})
return url
}
// const createQrCode = (name) => {
// const CW = 400, FONTSIZE = 30, FR = 2, CH = CW + FONTSIZE * FR;
// let url = ''
// // QRCode.toFile('F',name,
// // {
// // margin: 1,//二维码内边距,默认为4。单位px
// // height: CW,//二维码高度
// // width: CW,//二维码宽度
// // color: {
// // dark: '#000', //
// // light: '#fff' //
// // }
// // });
// QRCode.toDataURL(name, {
// errorCorrectionLevel: 'low',
// type: 'image/png',
// quality: 0.3,
// margin: 2,
// maskPattern: 9,
// width: 400,
// color: {
// dark: "#000000ff",
// light: "#ffffffff"
// }
// }, function (err, v) {
// url = v
// })
// // return url
// const canvas = createCanvas(CW, CH)
// const ctx = canvas.getContext('2d')
// ctx.clearRect(0, 0, CW, CH)
// ctx.fillStyle = 'rgba(255,255,255,1)'
// ctx.fillRect(0, 0, CW, CH)
// ctx.fillStyle = 'rgba(0,0,0,1)'
// ctx.font = `${FONTSIZE}px ZiTiQuanWeiJunHei`
// // ctx.font = `700 ${FONTSIZE}px `
// let image = loadImage(url)
// ctx.drawImage(image, 0, 0, CW, CW)
// const text = ctx.measureText(name)
// ctx.fillText(name, (CW - text.width) * 0.5, CH - FONTSIZE)
// canvas.toDataURL('image/png', (err, png) => {
// if (!err) {
// console.log(png);
// }
// })
// return url
// }
const columns = [
const columns = [
{
title: '序号',
dataIndex: 'index',
@ -151,14 +69,11 @@ const columns = [
key: 'operation',
render: (text, record, index) => {
return (
<div style={{ width: 224 }}>
<>
<Button type="link" onClick={() => {
setAddModel(true)
setModelData(record)
console.log(record);
}}
>编辑</Button>
}}>编辑</Button>
<Popconfirm
title={<div style={{ width: 184 }}>删除该点位后与巡检计划关联的点位删除对应的巡检记录删除是否确认删除</div>}
position='topLeft'
@ -171,46 +86,49 @@ const columns = [
projectList({ limit: query?.limit, page: query?.page - 1, ...search })
setQuery({ limit: query?.limit, page: query?.page - 1 });
}
}
})
}}
>
<Button type="link" danger >删除</Button>
</Popconfirm>
{/* <Button type="link" danger >二维码生成</Button> */}
<Button type="link" onClick={() => {
let url = createQrCode('FS' + Date.now() + record.id)
console.log(url);
setQrCodeingIds([record.id])
dispatch(projectRegime.addPosition({
qrCode: url,
qrCode: true,
id: record.id,
}, true))
}} >二维码生成</Button>
</div>
}, true)).then(() => {
setQrCodeingIds(null)
})
}} loading={qrCodeingIds?.includes(record.id)}>二维码生成</Button>
</>
)
}
}
]
]
return (
return (
<>
<img src={selec} />
<div style={{ display: 'flex', marginBottom: 10 }}>
<Button type="primary" onClick={() => {
setAddModel(true)
}}>新建点位</Button>
<Button type="primary" style={{ marginLeft: 20 }} onClick={() => {
select?.map(v => {
let url = createQrCode('FS' + Date.now() + v.id)
console.log(url);
if (select.length) {
setQrCodeingIds(select.map(s => s.id));
select?.map((v, i) => {
dispatch(projectRegime.addPosition({
qrCode: url,
qrCode: true,
id: v.id,
}, true))
}, true)).then(() => {
if (i === select.length - 1) {
setQrCodeingIds(null);
}
})
}}>一键生成二维码</Button>
})
}
}} disabled={qrCodeingIds?.length}>一键生成二维码</Button>
</div>
<Table
@ -256,10 +174,10 @@ return (
/> : ""
}
</>
)
)
}
function mapStateToProps (state) {
function mapStateToProps(state) {
const { auth, global } = state;
return {
user: auth.user,

38
web/client/src/sections/projectRegime/containers/qrCode.js

@ -1,31 +1,13 @@
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { Spin, Card, Form, Input, Select, Button, Table, Modal, Popconfirm, Tooltip } from 'antd';
import moment from "moment";
import { Form, Input, Select, Button } from 'antd';
import '../style.less';
import ProjectAddModel from '../components/projectAddModel'
import QRCode from 'qrcode';
import { login } from '../../auth/actions/auth';
import { createCanvas, loadImage, registerFont } from 'canvas'
import { dataURItoBlob } from 'react-jsonschema-form/lib/utils';
const QrCode = (props) => {
const { dispatch, actions, user, loading } = props
const { dispatch, actions } = props
const { projectRegime } = actions
const [firmList, setFirmList] = useState([])
const [tableList, settableList] = useState([])
const [addModel, setAddModel] = useState(false)
const [modelData, setModelData] = useState({})
const [query, setQuery] = useState({ limit: 10, page: 0 })
const [limits, setLimits] = useState()
const [search, setSearch] = useState({})
const [isPicture, setIsPicture] = useState(false)
const [pictureUrl, setPictureUrl] = useState()
const [companyID, setCompanyId] = useState('')
useEffect(() => {
dispatch(projectRegime.getProjectList({ justStructure: true })).then(res => {
@ -34,8 +16,6 @@ const QrCode = (props) => {
}
})
projectList({})
// dispatch(projectRegime.q())
}, [])
const projectList = (obj) => {
@ -89,24 +69,22 @@ const QrCode = (props) => {
<span>结构物名称{firmList?.filter(u => u.value == v.projectId)[0]?.label}</span>
<span>点位名称{v.name}</span>
</div>
<img src={v.qrCode} style={{ display: 'inline-block', width: 260 }} />
<img src={`/_file-server/${v.qrCode}`} style={{ display: 'inline-block', width: 260 }} />
<div style={{
width: 260, height: 60, background: '#e1d4d42e', display: 'flex',
justifyContent: 'center', alignItems: 'center', borderTop: '1px solid #3c383824'
}}>
<a href={`${v.qrCode}.png`}>
<Button type="primary" onClick={() => {
const a = document.createElement('a')
const filename = firmList?.filter(u => u.value == v.projectId)[0]?.label + '(' + v.name + ')'
a.href = v.qrCode // picSrc 是图片 base64 码,可以直接给 img 的 src 属性,展示图片
const filenameArr = v.qrCode.split('/')
const filename = filenameArr[filenameArr.length - 1]
a.href = `/_file-server/${v.qrCode}`
a.download = filename
a.target = '_blank'
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}}>下载二维码</Button>
</a>
</div>
</div>
}
@ -118,7 +96,7 @@ const QrCode = (props) => {
)
}
function mapStateToProps (state) {
function mapStateToProps(state) {
const { auth, global } = state;
return {
user: auth.user,

Loading…
Cancel
Save