显示出入库记录菜单
This commit is contained in:
@@ -1,26 +0,0 @@
|
||||
import request from '@/utils/request'
|
||||
//审核列表
|
||||
export function listProcess(query) {
|
||||
return request({
|
||||
url: '/wisdom/signature/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
//提交审核
|
||||
export function auditData(query) {
|
||||
return request({
|
||||
url: '/wisdom/signature/audit',
|
||||
method: 'post',
|
||||
// params: query
|
||||
data:query
|
||||
})
|
||||
}
|
||||
export function uploadPic(query) {
|
||||
return request({
|
||||
url: '/wisdom/signature/uploadBase64',
|
||||
method: 'post',
|
||||
// params: query,
|
||||
data:query
|
||||
})
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import request from '@/utils/request'
|
||||
//审核列表
|
||||
export function recordListFun(query) {
|
||||
return request({
|
||||
url: '/wisdom/signature/user/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
44
src/api/wisdom/record.js
Normal file
44
src/api/wisdom/record.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询出入库记录列表
|
||||
export function listRecord(query) {
|
||||
return request({
|
||||
url: '/wisdom/record/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询出入库记录详细
|
||||
export function getRecord(id) {
|
||||
return request({
|
||||
url: '/wisdom/record/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增出入库记录
|
||||
export function addRecord(data) {
|
||||
return request({
|
||||
url: '/wisdom/record',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改出入库记录
|
||||
export function updateRecord(data) {
|
||||
return request({
|
||||
url: '/wisdom/record',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除出入库记录
|
||||
export function delRecord(id) {
|
||||
return request({
|
||||
url: '/wisdom/record/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
@@ -1,561 +0,0 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryRef" >
|
||||
<el-row :gutter="40">
|
||||
<!-- <el-col :span="5">
|
||||
<el-form-item label="出库时间" prop="rkTime">
|
||||
<el-date-picker clearable
|
||||
v-model="queryParams.rkTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择出库时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="项目号" prop="xmNo">
|
||||
<el-input
|
||||
v-model="queryParams.xmNo"
|
||||
placeholder="请输入项目号"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="订单编号" prop="sapNo">
|
||||
<el-input
|
||||
v-model="queryParams.sapNo"
|
||||
placeholder="请输入订单编号"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col> -->
|
||||
<el-col :span="5">
|
||||
<el-form-item label="单据号" prop="billNo">
|
||||
<el-input
|
||||
v-model="queryParams.billNo"
|
||||
placeholder="请输入单据号"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<el-table :data="examineList" >
|
||||
<el-table-column label="单据号" align="center" prop="billNo" />
|
||||
<el-table-column label="单据类型" align="center" >
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.billType=="0"?"入库":"出库" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="出/入库类型" align="center" prop="rkTypeName" >
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.billType=="0"?scope.row.rkTypeName:scope.row.ckTypeName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="物资类型" align="center" prop="wlTypeName" />
|
||||
<el-table-column label="仓库" align="center" prop="cangkuName" />
|
||||
<el-table-column label="理货员" align="center" prop="lihuoYName" />
|
||||
<el-table-column label="提交时间" align="center" >
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" icon="Edit" @click="auditFun(scope.row)" >审核</el-button>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<!-- 审核弹框 -->
|
||||
<el-dialog title="审核" v-model="open" append-to-body width="60%" >
|
||||
<div id="capture">
|
||||
<div class="titleBox">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<span>出/入库类型:</span>
|
||||
<span>{{ auditInfo.billType=="0"?auditInfo.rkTypeName:auditInfo.ckTypeName }}</span>
|
||||
</el-col>
|
||||
<el-col :span="6" v-show="auditInfo.billType=='0'">
|
||||
<span>物资类型:</span>
|
||||
<span>{{ auditInfo.wlTypeName }}</span>
|
||||
</el-col>
|
||||
<el-col :span="6" v-show="auditInfo.billType=='1'">
|
||||
<span>施工队:</span>
|
||||
<span>{{ auditInfo.teamName }}</span>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<span>所属仓库:</span>
|
||||
<span>{{ auditInfo.cangkuName }}</span>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<span>理货员:</span>
|
||||
<span>{{ auditInfo.lihuoYName }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div>
|
||||
<el-table :data="auditList" height="400">
|
||||
<el-table-column label="物料号" prop="wlNo" />
|
||||
<el-table-column label="物料描述" prop="wlMs" />
|
||||
<el-table-column label="库位" prop="pcode" />
|
||||
<el-table-column label="供应商" prop="gysMc" />
|
||||
<el-table-column label="项目编号" prop="xmNo" />
|
||||
<el-table-column label="项目描述" prop="xmMs" />
|
||||
<el-table-column label="现场图片" align="center" >
|
||||
<template #default="scope">
|
||||
<!-- src="/src/assets/images/profile.jpg" -->
|
||||
<el-image style="width: 50px; height: 50px" :src="scope.row.signUrl"
|
||||
:zoom-rate="1.2"
|
||||
:max-scale="7"
|
||||
:min-scale="0.2"
|
||||
:preview-src-list="srcList"
|
||||
show-progress
|
||||
:initial-index="4"
|
||||
@click="preview(scope.row.signUrl)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="examine" >
|
||||
<div class="signBotBox">
|
||||
<div>备注:</div>
|
||||
<el-input
|
||||
v-model="submitData.remark"
|
||||
style="width: 400px;"
|
||||
:rows="3"
|
||||
type="textarea"
|
||||
placeholder="备注或驳回理由"
|
||||
/>
|
||||
</div>
|
||||
<div class="signBotBox">
|
||||
<div>签字:</div>
|
||||
<img :src="signatureimgSrcScale">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm(1)">通 过</el-button>
|
||||
<el-button type="danger" @click="submitForm(0)">驳 回</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 签名弹框 -->
|
||||
<el-dialog title="签名" v-model="signOpen" append-to-body width="650px" >
|
||||
<div class="signBox" style="height:200px;background-color: rgb(221 216 216);">
|
||||
<canvas id="signCanvas" width="600px" height="200px"/>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="clear">清 除</el-button>
|
||||
<el-button type="danger" @click="review">确 定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 图片预览 -->
|
||||
<!-- <el-dialog v-model="dialogVisible">
|
||||
<img w-full :src="dialogImageUrl" alt="Preview Image" />
|
||||
</el-dialog> -->
|
||||
<!-- <div>
|
||||
<img :src="htmlimgUrl">
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
<!-- https://www.jb51.net/javascript/335658hzv.htm -->
|
||||
<script name="examine">
|
||||
import SignaturePad from 'signature_pad'
|
||||
import html2canvas from 'html2canvas'
|
||||
import { listProcess,auditData,uploadPic } from "@/api/examine/process";
|
||||
// import { getInfo } from '@/api/login'
|
||||
import { getUserId } from "@/utils/auth";
|
||||
|
||||
export default{
|
||||
data(){
|
||||
return {
|
||||
imgUrl: '/src/assets/images/avatar.jpg',
|
||||
signatureimgSrc: null,
|
||||
htmlimgUrl: null,
|
||||
signatureExample: null,
|
||||
mergedImage: null,
|
||||
signatureimgSrcScale: null,
|
||||
|
||||
open:false, //审核弹框
|
||||
signOpen:false, //签名弹框
|
||||
examineList:[], //审核数据列表
|
||||
auditInfo:{},
|
||||
auditList:[], //审核详情页面列表
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
approverId:null,
|
||||
auditResult:2 //待审核 0驳回,1通过,2待审核
|
||||
},
|
||||
total:0,
|
||||
userId:null,
|
||||
srcList:[], //预览图片列表
|
||||
submitData:{
|
||||
auditResult:"", //审核结果 0通过 1驳回
|
||||
remark:"",
|
||||
approverSignUrl:"",
|
||||
billNo:"",
|
||||
id:null
|
||||
}
|
||||
// dialogVisible:false,
|
||||
// dialogImageUrl:""
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
// this.getUserInfo()
|
||||
this.getList()
|
||||
},
|
||||
methods:{
|
||||
// getUserInfo(){
|
||||
// getInfo().then(res => {
|
||||
// const user = res.user
|
||||
|
||||
// let id = user.userId
|
||||
// this.getList(id)
|
||||
|
||||
// })
|
||||
// },
|
||||
getList(){
|
||||
// console.log(333333)
|
||||
this.userId = getUserId()
|
||||
// console.log(this.userId)
|
||||
|
||||
// this.loading = false
|
||||
this.queryParams.approverId = this.userId
|
||||
listProcess(this.queryParams).then(response=>{
|
||||
if(response.code==200){
|
||||
this.examineList = response.rows
|
||||
}
|
||||
// console.log(111111)
|
||||
// console.log(response)
|
||||
})
|
||||
},
|
||||
preview(url){
|
||||
this.srcList = [url]
|
||||
// this.dialogVisible = true
|
||||
// this.dialogImageUrl = url
|
||||
},
|
||||
|
||||
//打开审核弹框
|
||||
auditFun(row){
|
||||
this.signatureimgSrcScale = ""
|
||||
this.htmlimgUrl = ""
|
||||
this.open = true
|
||||
this.auditList = row.scenePhotos
|
||||
this.auditInfo = row
|
||||
// this.$nextTick(()=>{
|
||||
// const canvas = document.getElementById('signCanvas')
|
||||
// this.signatureExample = new SignaturePad(canvas, { penColor: 'rgb(0, 0, 0)' }) //penColor 笔的颜色
|
||||
// this.adjustSignatureImgPos()
|
||||
// })
|
||||
|
||||
},
|
||||
handleQuery(){
|
||||
this.getList()
|
||||
// this.getUserInfo()
|
||||
},
|
||||
resetQuery(){
|
||||
|
||||
},
|
||||
//校正签名位置偏移
|
||||
adjustSignatureImgPos() {
|
||||
// console.log(3333)
|
||||
const canvas = document.getElementById('signCanvas')
|
||||
// console.log(11111)
|
||||
// console.log(canvas)
|
||||
const ratio = Math.max(window.devicePixelRatio || 1, 1) // 清除画布
|
||||
canvas.width = canvas.offsetWidth * ratio
|
||||
canvas.height = canvas.offsetHeight * ratio
|
||||
canvas.getContext('2d').scale(ratio, ratio)
|
||||
},
|
||||
//html页面内容转为base64
|
||||
html2base64(){
|
||||
// const canvasData = await html2canvas(document.querySelector("#capture"))
|
||||
// // this.htmlimgUrl = canvasData.toDataURL("image/png");
|
||||
// let htmlimgUrl = canvasData.toDataURL("image/png");
|
||||
// return htmlimgUrl
|
||||
html2canvas(document.querySelector("#capture"),{useCORS:true}).then(canvas => {
|
||||
this.htmlimgUrl = canvas.toDataURL("image/png"); // 将canvas转换成img的src流
|
||||
|
||||
// console.log(aa)
|
||||
// console.log(this.htmlimgUrl)
|
||||
});
|
||||
},
|
||||
//合并图片
|
||||
mergeimg(imgUrl,signatureimgSrc){
|
||||
// 创建一个 canvas 元素
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 创建两个图像对象
|
||||
const img1 = new Image();
|
||||
const img2 = new Image();
|
||||
|
||||
// 设置图像的 src 属性为 Base64 编码的字符串
|
||||
img1.src = imgUrl;
|
||||
img2.src = signatureimgSrc;
|
||||
|
||||
// 等待两张图像都加载完毕
|
||||
// await Promise.all([this.loadImage(img1), this.loadImage(img2)]);
|
||||
|
||||
// 设置 canvas 的宽度和高度
|
||||
// 这里假设我们将图像水平排列,因此宽度是两幅图宽度之和,高度取最大值
|
||||
canvas.width = img1.width + img2.width;
|
||||
canvas.height = Math.max(img1.height, img2.height);
|
||||
|
||||
// 绘制第一张图像
|
||||
ctx.drawImage(img1, 0, 0);
|
||||
// 绘制第二张图像,放置在第一张图像的右边
|
||||
ctx.drawImage(img2, 50, 150);
|
||||
|
||||
// 将合并后的图像导出为 Base64 编码的字符串
|
||||
this.mergedImage = canvas.toDataURL('image/png');
|
||||
},
|
||||
loadImage(img) {
|
||||
return new Promise((resolve, reject) => {
|
||||
img.onload = resolve;
|
||||
img.onerror = reject;
|
||||
});
|
||||
},
|
||||
|
||||
//点击清除按钮 清除签名面板内容
|
||||
clear(){
|
||||
//清除签名面板的方法
|
||||
this.signatureExample.clear()
|
||||
},
|
||||
// 签名 确定
|
||||
async review(){
|
||||
this.signatureimgSrc =this.signatureExample.toDataURL('image/png')
|
||||
this.signatureimgSrcScale =await this.resizeImage(this.signatureExample.toDataURL('image/png'))
|
||||
|
||||
// let aa = this.base64ToFile(this.signatureimgSrcScale,"aaa.png")
|
||||
// console.log(aa)
|
||||
this.signOpen = false
|
||||
// console.log("======== this.signatureimgSrc==========", this.signatureimgSrc)
|
||||
|
||||
},
|
||||
//点击提交 进行合并图片 保存签名面板内容
|
||||
submit(){
|
||||
// this.mergeimg(this.imgUrl,this.signatureimgSrcScale)
|
||||
this.mergeimg(this.htmlimgUrl,this.signatureimgSrcScale)
|
||||
|
||||
},
|
||||
// 绘制的canvas 进行缩放并转为base64
|
||||
resizeImage(src) {
|
||||
return new Promise((resolve) => {
|
||||
const img = new Image()
|
||||
img.src = src
|
||||
img.onload = () => {
|
||||
const originalWidth = img.width
|
||||
const originalHeight = img.height
|
||||
const scaleFactor = 0.5 // 缩放的倍数
|
||||
const resizedWidth = originalWidth * scaleFactor
|
||||
const resizedHeight = originalHeight * scaleFactor
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.width = resizedWidth
|
||||
canvas.height = resizedHeight
|
||||
const ctx = canvas.getContext('2d')
|
||||
ctx.drawImage(img, 0, 0, resizedWidth, resizedHeight)
|
||||
const base64 = canvas.toDataURL('image/png')
|
||||
resolve(base64)
|
||||
}
|
||||
})
|
||||
},
|
||||
//没签名的话打开签名弹框、已签名的话提交数据 1通过 0驳回 2审核中
|
||||
submitForm(type){
|
||||
// this.html2base64()
|
||||
// return
|
||||
//提交数据
|
||||
this.submitData.auditResult = type
|
||||
this.submitData.billNo = this.auditInfo.billNo
|
||||
this.submitData.id = this.auditInfo.id
|
||||
this.submitData.approverSignUrl = ""
|
||||
if(type==1){
|
||||
if(this.signatureimgSrcScale){
|
||||
html2canvas(document.querySelector("#capture"),{useCORS:true}).then(canvas => {
|
||||
this.htmlimgUrl = canvas.toDataURL("image/png"); // 将canvas转换成img的src流
|
||||
let obj = {
|
||||
"imgStr":this.htmlimgUrl
|
||||
}
|
||||
uploadPic(obj).then(response=>{
|
||||
if(response.url){
|
||||
|
||||
this.submitData.approverSignUrl = response.url
|
||||
auditData(this.submitData).then(response=>{
|
||||
this.open = false
|
||||
// this.getUserInfo()
|
||||
this.getList()
|
||||
// console.log(333333)
|
||||
// console.log(response)
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
}else{
|
||||
this.signOpen = true
|
||||
this.$nextTick(()=>{
|
||||
const canvas = document.getElementById('signCanvas')
|
||||
this.signatureExample = new SignaturePad(canvas, { penColor: 'rgb(0, 0, 0)' }) //penColor 笔的颜色
|
||||
this.adjustSignatureImgPos()
|
||||
})
|
||||
}
|
||||
|
||||
}else if(type==0){
|
||||
if(!this.submitData.remark){
|
||||
this.$message.error('驳回理由不能为空');
|
||||
return
|
||||
}
|
||||
auditData(this.submitData).then(response=>{
|
||||
this.open = false
|
||||
// this.getUserInfo()
|
||||
this.getList()
|
||||
// console.log(333333)
|
||||
// console.log(response)
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
//签完字提交数据
|
||||
submitFun(){
|
||||
if(!this.signatureimgSrcScale){
|
||||
this.$message.error('签名不能为空');
|
||||
}
|
||||
},
|
||||
// base64ToFile(base64String, fileName) {
|
||||
// const arr = base64String.split(',');
|
||||
// const mime = arr[0].match(/:(.*?);/)[1];
|
||||
// const bstr = atob(arr[1]);
|
||||
// let n = bstr.length;
|
||||
// const u8arr = new Uint8Array(n);
|
||||
|
||||
// while (n--) {
|
||||
// u8arr[n] = bstr.charCodeAt(n);
|
||||
// }
|
||||
|
||||
// return new File([u8arr], fileName, { type: mime });
|
||||
// },
|
||||
base64ToFile(base64Data, filename) {
|
||||
// 提取出base64中的数据部分(去掉前缀)
|
||||
const base64String = base64Data.split(',')[1];
|
||||
|
||||
// 将base64数据解码成字节数组
|
||||
const byteCharacters = atob(base64String);
|
||||
|
||||
// 创建字节数组
|
||||
const byteArray = new Uint8Array(byteCharacters.length);
|
||||
|
||||
// 将字节赋值到字节数组中
|
||||
for (let i = 0; i < byteCharacters.length; i++) {
|
||||
byteArray[i] = byteCharacters.charCodeAt(i);
|
||||
}
|
||||
|
||||
// 创建文件对象
|
||||
const file = new File([byteArray], filename, { type: 'image/jpeg' }); // 根据实际类型修改 mime 类型
|
||||
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
// const { proxy } = getCurrentInstance();
|
||||
// const loading = ref(true);
|
||||
// const showSearch = ref(true);
|
||||
// const open = ref(false)
|
||||
// const storeData = ref({
|
||||
// aa:"测试"
|
||||
// })
|
||||
// const data = reactive({
|
||||
// form: {},
|
||||
// examineList:[{aa:"测试"}], //审核数据列表
|
||||
// auditList:[{aa:"测试"}], //审核详情页面列表
|
||||
// queryParams: {
|
||||
// pageNum: 1,
|
||||
// pageSize: 10,
|
||||
// isChuku:1, //出库,固定传1
|
||||
// rkTime:"", //出库时间
|
||||
// xmNo:"",
|
||||
// sapNo:"",
|
||||
// billNo:""
|
||||
// },
|
||||
|
||||
// rules: {
|
||||
// ckType: [{ required: true, message: "出库类型不能为空", trigger: "change" }],
|
||||
// teamCode: [{ required: true, message: "施工队不能为空", trigger: "change" }],
|
||||
// lyTime: [{ required: true, message: "领用时间不能为空", trigger: "change" }],
|
||||
// ckLihuoY: [{ required: true, message: "理货员不能为空", trigger: "change" }]
|
||||
// }
|
||||
|
||||
// });
|
||||
|
||||
// const { queryParams,examineList,auditList,rules } = toRefs(data);
|
||||
|
||||
/** 查询库存单据主列表 */
|
||||
// function getList() {
|
||||
// loading.value = false;
|
||||
|
||||
// }
|
||||
// function handleQuery() {
|
||||
|
||||
// }
|
||||
// /** 重置按钮操作 */
|
||||
// function resetQuery() {
|
||||
// proxy.resetForm("queryRef");
|
||||
// handleQuery();
|
||||
// }
|
||||
// function auditFun(){
|
||||
// open.value = true;
|
||||
// }
|
||||
// getList()
|
||||
</script>
|
||||
<style>
|
||||
.titleBox{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.examine{
|
||||
/* background-color: #ededed;
|
||||
border-radius: 10px;
|
||||
margin-top: 20px;
|
||||
padding:10px 0 0 10px; */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 20px;
|
||||
background-color: #fff;
|
||||
.signBotBox{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 43%;
|
||||
}
|
||||
/* .signBox{
|
||||
width:300px;height:200px;
|
||||
background-color: rgb(221 216 216);
|
||||
} */
|
||||
}
|
||||
.el-textarea__inner{
|
||||
background-color: #f8f8f9;
|
||||
}
|
||||
</style>
|
||||
@@ -1,172 +0,0 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div id="capture">
|
||||
<div>测试</div>
|
||||
<div>测试2</div>
|
||||
<div>测试3</div>
|
||||
<button type="default" @click="html2base64()">文档转图片</button>
|
||||
</div>
|
||||
<div>
|
||||
<h3>原文档</h3>
|
||||
<h3>-----------------------</h3>
|
||||
<img :src="htmlimgUrl">
|
||||
</div>
|
||||
|
||||
<div class="sign-box" style="width:300px;height:200px;padding: 10px; margin:10px;background-color: rgb(221 216 216);">
|
||||
<p><span style="color: #f00;">*</span>签名版<span style="color: #f00;">*</span></p>
|
||||
<div>
|
||||
<canvas id="signCanvas"/>
|
||||
</div>
|
||||
<button type="default" @click="clear()">清除</button>
|
||||
<button type="default" @click="review()">游览</button>
|
||||
<button aria-placeholder="添加签名到文件" type="default" @click="submit()">提交</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>签名</h3>
|
||||
<img :src="signatureimgSrcScale">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>签名后的文档</h3>
|
||||
<h3>-----------------------</h3>
|
||||
<img :src="mergedImage">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script >
|
||||
import SignaturePad from 'signature_pad'
|
||||
import html2canvas from 'html2canvas'
|
||||
// import pdf from 'vue-pdf'
|
||||
|
||||
export default {
|
||||
// components: {
|
||||
// pdf
|
||||
// },
|
||||
data() {
|
||||
return {
|
||||
// imgUrl: 'http://127.0.0.1:8080/avatar.jpg',
|
||||
imgUrl: '/src/assets/images/avatar.jpg',
|
||||
signatureimgSrc: null,
|
||||
htmlimgUrl: null,
|
||||
signatureExample: null,
|
||||
mergedImage: null,
|
||||
signatureimgSrcScale: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const canvas = document.getElementById('signCanvas')
|
||||
this.signatureExample = new SignaturePad(canvas, { penColor: 'rgb(0, 0, 0)' }) //penColor 笔的颜色
|
||||
this.adjustSignatureImgPos()
|
||||
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
//校正签名位置偏移
|
||||
adjustSignatureImgPos() {
|
||||
const canvas = document.getElementById('signCanvas')
|
||||
const ratio = Math.max(window.devicePixelRatio || 1, 1) // 清除画布
|
||||
canvas.width = canvas.offsetWidth * ratio
|
||||
canvas.height = canvas.offsetHeight * ratio
|
||||
canvas.getContext('2d').scale(ratio, ratio)
|
||||
},
|
||||
//html页面内容转为base64
|
||||
html2base64(){
|
||||
html2canvas(document.querySelector("#capture")).then(canvas => {
|
||||
this.htmlimgUrl = canvas.toDataURL("image/png"); // 将canvas转换成img的src流
|
||||
console.log(this.htmlimgUrl)
|
||||
});
|
||||
},
|
||||
//合并图片
|
||||
mergeimg(imgUrl,signatureimgSrc){
|
||||
// 创建一个 canvas 元素
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 创建两个图像对象
|
||||
const img1 = new Image();
|
||||
const img2 = new Image();
|
||||
|
||||
// 设置图像的 src 属性为 Base64 编码的字符串
|
||||
img1.src = imgUrl;
|
||||
img2.src = signatureimgSrc;
|
||||
|
||||
// 等待两张图像都加载完毕
|
||||
// await Promise.all([this.loadImage(img1), this.loadImage(img2)]);
|
||||
|
||||
// 设置 canvas 的宽度和高度
|
||||
// 这里假设我们将图像水平排列,因此宽度是两幅图宽度之和,高度取最大值
|
||||
canvas.width = img1.width + img2.width;
|
||||
canvas.height = Math.max(img1.height, img2.height);
|
||||
|
||||
// 绘制第一张图像
|
||||
ctx.drawImage(img1, 0, 0);
|
||||
// 绘制第二张图像,放置在第一张图像的右边
|
||||
ctx.drawImage(img2, 50, 150);
|
||||
|
||||
// 将合并后的图像导出为 Base64 编码的字符串
|
||||
this.mergedImage = canvas.toDataURL('image/png');
|
||||
},
|
||||
loadImage(img) {
|
||||
return new Promise((resolve, reject) => {
|
||||
img.onload = resolve;
|
||||
img.onerror = reject;
|
||||
});
|
||||
},
|
||||
|
||||
//点击清除按钮 清除签名面板内容
|
||||
clear(){
|
||||
//清除签名面板的方法
|
||||
this.signatureExample.clear()
|
||||
},
|
||||
async review(){
|
||||
this.signatureimgSrc =this.signatureExample.toDataURL('image/png')
|
||||
this.signatureimgSrcScale =await this.resizeImage(this.signatureExample.toDataURL('image/png'))
|
||||
|
||||
console.log("======== this.signatureimgSrc==========", this.signatureimgSrc)
|
||||
|
||||
},
|
||||
//点击提交 进行合并图片 保存签名面板内容
|
||||
submit(){
|
||||
// this.mergeimg(this.imgUrl,this.signatureimgSrcScale)
|
||||
this.mergeimg(this.htmlimgUrl,this.signatureimgSrcScale)
|
||||
|
||||
},
|
||||
// 绘制的canvas 进行缩放并转为base64
|
||||
resizeImage(src) {
|
||||
return new Promise((resolve) => {
|
||||
const img = new Image()
|
||||
img.src = src
|
||||
img.onload = () => {
|
||||
const originalWidth = img.width
|
||||
const originalHeight = img.height
|
||||
const scaleFactor = 0.5 // 缩放的倍数
|
||||
const resizedWidth = originalWidth * scaleFactor
|
||||
const resizedHeight = originalHeight * scaleFactor
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.width = resizedWidth
|
||||
canvas.height = resizedHeight
|
||||
const ctx = canvas.getContext('2d')
|
||||
ctx.drawImage(img, 0, 0, resizedWidth, resizedHeight)
|
||||
const base64 = canvas.toDataURL('image/png')
|
||||
resolve(base64)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.page{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: 10px;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,180 +0,0 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" >
|
||||
<el-row :gutter="40">
|
||||
<el-col :span="5">
|
||||
<el-form-item label="单据号" prop="billNo">
|
||||
<el-input
|
||||
v-model="queryParams.billNo"
|
||||
placeholder="请输入单据号"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<el-table v-loading="loading" :data="recordList" >
|
||||
|
||||
<!-- <el-table-column label="主键ID" align="center" prop="id" />-->
|
||||
<el-table-column label="单据号" align="center" prop="billNo" />
|
||||
<el-table-column label="类型" align="center" >
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.billType==0?"入库":"出库" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核状态" align="center" >
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.auditResult==1?"通过":(scope.row.auditResult==0?"驳回":"审核中") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="签字图片" align="center" prop="lihuoY" >
|
||||
<template #default="scope">
|
||||
<el-image :src="scope.row.approverSignUrl" style="width: 50px; height: 50px"
|
||||
:zoom-rate="1.2"
|
||||
:max-scale="7"
|
||||
:min-scale="0.2"
|
||||
:preview-src-list="srcList"
|
||||
show-progress
|
||||
:initial-index="4"
|
||||
:preview-teleported="true"
|
||||
@click="preview(scope.row.approverSignUrl)"
|
||||
v-show="scope.row.approverSignUrl"
|
||||
/>
|
||||
<span v-show="!scope.row.approverSignUrl">暂无图片</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark" width="200"/>
|
||||
<el-table-column label="提交时间" align="center" >
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" icon="Edit" @click="auditDetail(scope.row)" >明细</el-button>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<el-dialog title="明细" v-model="open" append-to-body width="60%" >
|
||||
<el-table :data="detailList" height="400">
|
||||
<el-table-column label="物料号" prop="wlNo" />
|
||||
<el-table-column label="物料描述" prop="wlMs" />
|
||||
<el-table-column label="库位" prop="pcode" />
|
||||
<el-table-column label="供应商" prop="gysMc" />
|
||||
<el-table-column label="项目编号" prop="xmNo" />
|
||||
<el-table-column label="项目描述" prop="xmMs" />
|
||||
<el-table-column label="现场图片" align="center" >
|
||||
<template #default="scope" >
|
||||
<el-image style="width: 50px; height: 50px" :src="scope.row.signUrl"
|
||||
:zoom-rate="1.2"
|
||||
:max-scale="7"
|
||||
:min-scale="0.2"
|
||||
:preview-src-list="srcList"
|
||||
show-progress
|
||||
:initial-index="4"
|
||||
@click="preview(scope.row.signUrl)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="record">
|
||||
import { recordListFun } from "@/api/examine/record";
|
||||
// import { getInfo } from '@/api/login'
|
||||
import { getUserId } from "@/utils/auth";
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const recordList = ref([]);
|
||||
const detailList = ref([]);
|
||||
const total = ref(0);
|
||||
const srcList = ref([]);
|
||||
const open = ref(false);
|
||||
const userId = ref(0);
|
||||
const data = reactive({
|
||||
queryParams:{
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
signerId:null,
|
||||
}
|
||||
})
|
||||
const { queryParams } = toRefs(data);
|
||||
// 表单重置
|
||||
function reset() {
|
||||
planList.value = []
|
||||
storeData.value = {}
|
||||
proxy.resetForm("stockRef");
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
|
||||
|
||||
// console.log(queryParams.value.rkTime.length)
|
||||
// console.log(queryParams.value)
|
||||
// return
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
proxy.resetForm("queryRef");
|
||||
|
||||
// queryParams.value.startTime = ""
|
||||
// queryParams.value.endTime = ""
|
||||
handleQuery();
|
||||
}
|
||||
// function getList(){
|
||||
// loading.value = true;
|
||||
// getInfo().then(res => {
|
||||
// const user = res.user
|
||||
// queryParams.value.signerId = user.userId
|
||||
// recordListFun(queryParams.value).then(response => {
|
||||
// recordList.value = response.rows;
|
||||
// total.value = response.total;
|
||||
// loading.value = false;
|
||||
// });
|
||||
|
||||
// })
|
||||
|
||||
// }
|
||||
function getList(){
|
||||
loading.value = true;
|
||||
// userId.value = getUserId()
|
||||
queryParams.value.signerId = getUserId()
|
||||
recordListFun(queryParams.value).then(response => {
|
||||
recordList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
function auditDetail(row){
|
||||
detailList.value = row.scenePhotos
|
||||
open.value = true
|
||||
// console.log(22222)
|
||||
}
|
||||
function preview(url){
|
||||
srcList.value = [url]
|
||||
}
|
||||
getList()
|
||||
</script>
|
||||
<style>
|
||||
</style>
|
||||
@@ -338,7 +338,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="stockSearch">
|
||||
<script setup name="Record">
|
||||
// wisdomDelStock
|
||||
import { listStock,getSumInfoI} from "@/api/wisdom/stockSearch";
|
||||
import { getToken } from "@/utils/auth";
|
||||
Reference in New Issue
Block a user