入库流程对接完毕
This commit is contained in:
24
api/getRepository.js
Normal file
24
api/getRepository.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// mockWarehousing.js
|
||||||
|
|
||||||
|
// 模拟数据
|
||||||
|
const mockWarehousingData = [
|
||||||
|
{ id: 101, deptName: "Y00002", deptId: "WSA0197", remark: "备注" },
|
||||||
|
{ id: 102, deptName: "Y00003", deptId: "WSA0198", remark: "" },
|
||||||
|
{ id: 103, deptName: "Y00004", deptId: "WSA0199", remark: "备注" },
|
||||||
|
{ id: 104, deptName: "Y00005", deptId: "WSA0200", remark: "" },
|
||||||
|
];
|
||||||
|
|
||||||
|
// Mock 接口(和你原接口格式一致)
|
||||||
|
const getRepository = (params) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve({
|
||||||
|
code: 200,
|
||||||
|
msg: "获取成功",
|
||||||
|
data: mockWarehousingData,
|
||||||
|
});
|
||||||
|
}, 200);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getRepository;
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
//存放主站域名
|
//存放主站域名
|
||||||
const BASE_URL = 'http://192.168.1.5:8082' // 正式环境接口
|
// const BASE_URL = 'http://192.168.1.5:8082' // w
|
||||||
|
const BASE_URL = 'http://192.168.1.9:8082' // 正式环境接口
|
||||||
// const BASE_URL = 'http://47.100.212.83:18088' // 正式环境接口
|
// const BASE_URL = 'http://47.100.212.83:18088' // 正式环境接口
|
||||||
// const BASE_URL = 'http://192.168.1.9:8088' // 测试环境接口
|
// const BASE_URL = 'http://192.168.1.9:8088' // 测试环境接口
|
||||||
// const BASE_URL = 'http://192.168.1.5:8088' // 测试环境接口
|
// const BASE_URL = 'http://192.168.1.5:8088' // 测试环境接口
|
||||||
|
|||||||
37
api/stockIn.js
Normal file
37
api/stockIn.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { request } from './request'
|
||||||
|
const api ='/worn/inboundBill/'
|
||||||
|
// 新建:入库单
|
||||||
|
const addStockIn = (params) => {
|
||||||
|
return request(api+'add', params, 'POST')
|
||||||
|
}
|
||||||
|
// 列表
|
||||||
|
const stockList = (params) => {
|
||||||
|
return request(api+'list', params, 'get')
|
||||||
|
}
|
||||||
|
// 详情
|
||||||
|
const stockInDetail = (params) => {
|
||||||
|
return request('/worn/item/list', params, 'get')
|
||||||
|
}
|
||||||
|
// 编辑
|
||||||
|
const stockInUpdate = (params) => {
|
||||||
|
return request('/worn/item/update', params, 'post')
|
||||||
|
}
|
||||||
|
// 入库
|
||||||
|
const inboundFinish = (params) => {
|
||||||
|
return request('/worn/inboundBill/inboundFinish', params, 'post')
|
||||||
|
}
|
||||||
|
// 作废
|
||||||
|
const inboundBillVoid = (params) => {
|
||||||
|
return request('/worn/inboundBill/void', params, 'post')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export {
|
||||||
|
addStockIn,
|
||||||
|
stockList,
|
||||||
|
stockInDetail,
|
||||||
|
stockInUpdate,
|
||||||
|
inboundFinish,
|
||||||
|
inboundBillVoid
|
||||||
|
|
||||||
|
}
|
||||||
8
api/system.js
Normal file
8
api/system.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { request } from "./request";
|
||||||
|
|
||||||
|
// 根据当前用户获取仓库信息
|
||||||
|
const getWarehousingInfo = (params) => {
|
||||||
|
return request(`/system/user/myDeptChildren`, params, "get");
|
||||||
|
};
|
||||||
|
|
||||||
|
export { getWarehousingInfo };
|
||||||
@@ -21,9 +21,12 @@ const delUniqueCode = (params) => {
|
|||||||
};
|
};
|
||||||
// 详情:唯一码
|
// 详情:唯一码
|
||||||
const detailUniqueCode = (params) => {
|
const detailUniqueCode = (params) => {
|
||||||
console.log(params,'params');
|
|
||||||
return request(`/unique/code/${params.id}`, params, 'GET');
|
return request(`/unique/code/${params.id}`, params, 'GET');
|
||||||
};
|
};
|
||||||
|
// 详情:通过唯一码获取物料信息
|
||||||
|
const getMaterialUnique = (params) => {
|
||||||
|
return request(`/unique/code/materialInfo/${params.code}`, params, 'GET');
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getMaterial,
|
getMaterial,
|
||||||
@@ -32,4 +35,5 @@ export {
|
|||||||
delUniqueCode,
|
delUniqueCode,
|
||||||
detailUniqueCode,
|
detailUniqueCode,
|
||||||
editUniqueCode,
|
editUniqueCode,
|
||||||
|
getMaterialUnique
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
<!-- components/BarcodeGenerator.vue -->
|
|
||||||
<template>
|
|
||||||
<div class="barcode-container">
|
|
||||||
<canvas v-if="type === 'canvas'" ref="barcodeRef"></canvas>
|
|
||||||
<svg v-else ref="barcodeRef"></svg>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, watch, onMounted, defineProps, defineEmits } from 'vue';
|
|
||||||
import JsBarcode from 'jsbarcode';
|
|
||||||
|
|
||||||
// 定义Props(外部传参)
|
|
||||||
const props = defineProps({
|
|
||||||
value: { // 条形码内容
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
format: { // 条形码格式
|
|
||||||
type: String,
|
|
||||||
default: 'CODE128'
|
|
||||||
},
|
|
||||||
type: { // 渲染类型
|
|
||||||
type: String,
|
|
||||||
default: 'canvas',
|
|
||||||
validator: (val) => ['canvas', 'svg'].includes(val)
|
|
||||||
},
|
|
||||||
options: { // 自定义配置
|
|
||||||
type: Object,
|
|
||||||
default: () => ({
|
|
||||||
width: 2,
|
|
||||||
height: 100,
|
|
||||||
displayValue: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 定义DOM引用
|
|
||||||
const barcodeRef = ref(null)
|
|
||||||
|
|
||||||
// 生成条形码
|
|
||||||
const generate = () => {
|
|
||||||
if (!barcodeRef.value) return
|
|
||||||
// 合并默认配置和外部配置
|
|
||||||
const finalOptions = { ...props.options, format: props.format }
|
|
||||||
// 清空Canvas(SVG无需清空)
|
|
||||||
if (props.type === 'canvas') {
|
|
||||||
const ctx = barcodeRef.value.getContext('2d')
|
|
||||||
ctx.clearRect(0, 0, barcodeRef.value.width, barcodeRef.value.height)
|
|
||||||
}
|
|
||||||
// 生成条形码
|
|
||||||
JsBarcode(barcodeRef.value, props.value, finalOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 挂载后初始化
|
|
||||||
onMounted(generate)
|
|
||||||
|
|
||||||
// 监听props变化,自动更新
|
|
||||||
watch([() => props.value, () => props.format, () => props.options], generate, { deep: true })
|
|
||||||
</script>
|
|
||||||
24
package-lock.json
generated
24
package-lock.json
generated
@@ -6,7 +6,10 @@
|
|||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@climblee/uv-ui": "^1.1.20",
|
"@climblee/uv-ui": "^1.1.20",
|
||||||
|
"dayjs": "^1.11.20",
|
||||||
"jsbarcode": "^3.12.3",
|
"jsbarcode": "^3.12.3",
|
||||||
|
"lodash": "^4.17.23",
|
||||||
|
"numeral": "^2.0.6",
|
||||||
"z-paging": "^2.8.8"
|
"z-paging": "^2.8.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -817,6 +820,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/dayjs": {
|
||||||
|
"version": "1.11.20",
|
||||||
|
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.20.tgz",
|
||||||
|
"integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/detect-libc": {
|
"node_modules/detect-libc": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz",
|
"resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||||
@@ -1107,6 +1116,12 @@
|
|||||||
"node": ">=8.9.0"
|
"node": ">=8.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash": {
|
||||||
|
"version": "4.17.23",
|
||||||
|
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.23.tgz",
|
||||||
|
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/merge-stream": {
|
"node_modules/merge-stream": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||||
@@ -1159,6 +1174,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/numeral": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmmirror.com/numeral/-/numeral-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
|
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@climblee/uv-ui": "^1.1.20",
|
"@climblee/uv-ui": "^1.1.20",
|
||||||
|
"dayjs": "^1.11.20",
|
||||||
"jsbarcode": "^3.12.3",
|
"jsbarcode": "^3.12.3",
|
||||||
|
"lodash": "^4.17.23",
|
||||||
|
"numeral": "^2.0.6",
|
||||||
"z-paging": "^2.8.8"
|
"z-paging": "^2.8.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
122
pages.json
122
pages.json
@@ -32,22 +32,117 @@
|
|||||||
"path": "pages/my/index",
|
"path": "pages/my/index",
|
||||||
"style": { "navigationBarTitleText": "我的" }
|
"style": { "navigationBarTitleText": "我的" }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 仓储 - 唯一码
|
||||||
{
|
{
|
||||||
"path": "pages/uniqueCode/issueUniqueCode/index",
|
"path": "pages/warehousing/uniqueCode/issueUniqueCode/index",
|
||||||
"style": { "navigationBarTitleText": "唯一码发放" }
|
"style": { "navigationBarTitleText": "唯一码发放" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/uniqueCode/issueUniqueCode/materialSelection",
|
"path": "pages/warehousing/uniqueCode/issueUniqueCode/materialSelection",
|
||||||
"style": { "navigationBarTitleText": "物料选择" }
|
"style": { "navigationBarTitleText": "物料选择" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/uniqueCode/myUniqueCode/index",
|
"path": "pages/warehousing/uniqueCode/myUniqueCode/index",
|
||||||
"style": { "navigationBarTitleText": "唯一码" }
|
"style": { "navigationBarTitleText": "唯一码" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/uniqueCode/myUniqueCode/detail",
|
"path": "pages/warehousing/uniqueCode/myUniqueCode/detail",
|
||||||
"style": { "navigationBarTitleText": "唯一码详情" }
|
"style": {
|
||||||
|
"navigationBarTitleText": "唯一码详情",
|
||||||
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// "path": "pages/uniqueCode/bindRfid",
|
||||||
|
// "style": { "navigationBarTitleText": "绑定RFID" }
|
||||||
|
// },
|
||||||
|
|
||||||
|
// ========== 库存信息模块 ==========
|
||||||
|
// {
|
||||||
|
// "path": "pages/inventory/checkUniqueCode",
|
||||||
|
// "style": { "navigationBarTitleText": "唯一码盘点" }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "path": "pages/inventory/age",
|
||||||
|
// "style": { "navigationBarTitleText": "库龄查看" }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "path": "pages/inventory/alert",
|
||||||
|
// "style": { "navigationBarTitleText": "库存预警" }
|
||||||
|
// },
|
||||||
|
|
||||||
|
// ========== 报表模块 ==========
|
||||||
|
// {
|
||||||
|
// "path": "pages/report/daily",
|
||||||
|
// "style": { "navigationBarTitleText": "库存日报" }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "path": "pages/report/monthly",
|
||||||
|
// "style": { "navigationBarTitleText": "库存月报" }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "path": "pages/report/company",
|
||||||
|
// "style": { "navigationBarTitleText": "公司库存报表" }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "path": "pages/report/warehouse",
|
||||||
|
// "style": { "navigationBarTitleText": "仓库库存报表" }
|
||||||
|
// },
|
||||||
|
|
||||||
|
// ========== 申报单模块 ==========
|
||||||
|
// {
|
||||||
|
// "path": "pages/declaration/materialQuery",
|
||||||
|
// "style": { "navigationBarTitleText": "物资查询" }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "path": "pages/declaration/create",
|
||||||
|
// "style": { "navigationBarTitleText": "申报单开单" }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "path": "pages/declaration/my",
|
||||||
|
// "style": { "navigationBarTitleText": "我的申报单" }
|
||||||
|
// },
|
||||||
|
|
||||||
|
// ========== 入库单模块 ==========
|
||||||
|
{
|
||||||
|
"path": "pages/warehousing/stockIn/create",
|
||||||
|
"style": { "navigationBarTitleText": "入库单开单" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/warehousing/stockIn/my",
|
||||||
|
"style": { "navigationBarTitleText": "我的入库单" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/warehousing/stockIn/components/detail",
|
||||||
|
"style": { "navigationBarTitleText": "详情", "navigationStyle": "custom" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/warehousing/stockIn/putaway",
|
||||||
|
"style": { "navigationBarTitleText": "入库单入库" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/warehousing/toChooseList",
|
||||||
|
"style": { "navigationBarTitleText": "请选择" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/warehousing/stockIn/components/inbound",
|
||||||
|
"style": { "navigationBarTitleText": "入库" }
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 出库单模块 ==========
|
||||||
|
// {
|
||||||
|
// "path": "pages/stockOut/create",
|
||||||
|
// "style": { "navigationBarTitleText": "出库单开单" }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "path": "pages/stockOut/my",
|
||||||
|
// "style": { "navigationBarTitleText": "我的出库单" }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "path": "pages/stockOut/warehousing",
|
||||||
|
// "style": { "navigationBarTitleText": "出库单出库" }
|
||||||
|
// }
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
"navigationBarTextStyle": "black",
|
"navigationBarTextStyle": "black",
|
||||||
@@ -55,18 +150,17 @@
|
|||||||
"navigationBarBackgroundColor": "#F5F5F5",
|
"navigationBarBackgroundColor": "#F5F5F5",
|
||||||
"backgroundColor": "#F5F5F5"
|
"backgroundColor": "#F5F5F5"
|
||||||
},
|
},
|
||||||
// 底部 tabBar 核心配置
|
|
||||||
"tabBar": {
|
"tabBar": {
|
||||||
"color": "#666", // 未选中文字颜色
|
"color": "#666",
|
||||||
"selectedColor": "#007AFF", // 选中文字颜色
|
"selectedColor": "#007AFF",
|
||||||
"backgroundColor": "#fff", // 导航栏背景色
|
"backgroundColor": "#fff",
|
||||||
"borderStyle": "black", // 上边框样式(black/white)
|
"borderStyle": "black",
|
||||||
"height": "50px", // 导航栏高度(App 端建议 50px 左右)
|
"height": "50px",
|
||||||
"list": [
|
"list": [
|
||||||
{
|
{
|
||||||
"pagePath": "pages/index/index", // 必须和 pages 中的路径一致
|
"pagePath": "pages/index/index",
|
||||||
"text": "首页", // 底部文字
|
"text": "首页",
|
||||||
"iconPath": "static/icon/home.png", // 未选中图标(建议 28x28px)
|
"iconPath": "static/icon/home.png",
|
||||||
"selectedIconPath": "static/icon/home-active.png"
|
"selectedIconPath": "static/icon/home-active.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
236
pages/components/ChooseList.vue
Normal file
236
pages/components/ChooseList.vue
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
<!-- 仓库/存储区选择 -->
|
||||||
|
<template>
|
||||||
|
<view class="content">
|
||||||
|
<view class="topSearch">
|
||||||
|
<uni-easyinput type="text" v-model="queryParams.keyword" prefixIcon="search" :inputBorder="false"
|
||||||
|
@iconClick="getList" placeholder="请输入搜索内容" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 仓库/存储列表 -->
|
||||||
|
<z-paging ref="pagingRef" class="containerBox" v-model="infoList" @query="getList">
|
||||||
|
<uni-list class="listBox">
|
||||||
|
<uni-list-item v-for="item in infoList" :key="item.id" clickable @click="onChecked(item)">
|
||||||
|
<template v-slot:body>
|
||||||
|
<view style="display: flex; flex-direction: column; width: 100%;" v-if="isWarehousing">
|
||||||
|
<view class="line title">
|
||||||
|
<p>仓库名称</p>
|
||||||
|
<p>{{ item.deptName }}</p>
|
||||||
|
</view>
|
||||||
|
<view class="line content">
|
||||||
|
<p>仓库编码</p>
|
||||||
|
<p>{{ item.deptId }}</p>
|
||||||
|
</view>
|
||||||
|
<!-- todo 以下两个字段pc未维护暂时注释 -->
|
||||||
|
<!-- <view class=" line content">
|
||||||
|
<p>仓库类型</p>
|
||||||
|
<p></p>
|
||||||
|
</view>
|
||||||
|
<view class="line content">
|
||||||
|
<p>仓库位置</p>
|
||||||
|
<p></p>
|
||||||
|
</view> -->
|
||||||
|
<view class="line content">
|
||||||
|
<p>备注</p>
|
||||||
|
<p>
|
||||||
|
<span v-if="item?.remark"></span>
|
||||||
|
<span v-else class="empty">未填写</span>
|
||||||
|
</p>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view v-else style="display: flex; flex-direction: column;width: 100%;">
|
||||||
|
<view class="line title">
|
||||||
|
<p>{{ item.deptName }} ({{ item.deptId }})</p>
|
||||||
|
</view>
|
||||||
|
<view class="line content">
|
||||||
|
<p>
|
||||||
|
<span v-if="item?.remark">{{ item?.remark }}</span>
|
||||||
|
<span v-else class="empty">未填写</span>
|
||||||
|
</p>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</uni-list-item>
|
||||||
|
</uni-list>
|
||||||
|
</z-paging>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, toRefs } from 'vue';
|
||||||
|
import { onShow } from "@dcloudio/uni-app";
|
||||||
|
import { getWarehousingInfo } from '../../api/system';
|
||||||
|
import getRepository from "@/api/getRepository";
|
||||||
|
import { objectToQuery } from '../until';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// 是否为仓库查询
|
||||||
|
isWarehousing: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
// 返回出库开单/入库开单
|
||||||
|
backStr: {
|
||||||
|
type: String,
|
||||||
|
default: true,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
pathParams: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
const { isWarehousing, backStr, pathParams } = toRefs(props)
|
||||||
|
// 数据:查询关键字
|
||||||
|
const queryParams = ref({
|
||||||
|
keyword: ''
|
||||||
|
})
|
||||||
|
// 绑定:加载屏
|
||||||
|
const pagingRef = ref(null)
|
||||||
|
// 数据:仓库/存储区
|
||||||
|
const infoList = ref([])
|
||||||
|
|
||||||
|
// 列表判断:获取仓库列表/存储库列表
|
||||||
|
const getList = () => {
|
||||||
|
if (isWarehousing.value) {
|
||||||
|
// 仓库列表
|
||||||
|
getWarehousing()
|
||||||
|
} else {
|
||||||
|
// 存储库列表
|
||||||
|
getRepositoryInfo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列表:仓库列表
|
||||||
|
const getWarehousing = () => {
|
||||||
|
const userInfo = uni.getStorageSync('app_user')
|
||||||
|
const params = {
|
||||||
|
userId: `${userInfo.userId}`,
|
||||||
|
keyword: queryParams.value.keyword
|
||||||
|
}
|
||||||
|
getWarehousingInfo(params).then(res => {
|
||||||
|
res.data.forEach(e => {
|
||||||
|
e.showMore = false;
|
||||||
|
});
|
||||||
|
pagingRef.value.complete(res.data)
|
||||||
|
}).catch(res => {
|
||||||
|
pagingRef.value.complete(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 列表:存储区列表
|
||||||
|
const getRepositoryInfo = async () => {
|
||||||
|
getRepository({ pageNum: 1, pageSize: 10 }).then(res => {
|
||||||
|
res.data.forEach(e => {
|
||||||
|
e.showMore = false;
|
||||||
|
});
|
||||||
|
pagingRef.value.complete(res.data)
|
||||||
|
}).catch(res => {
|
||||||
|
pagingRef.value.complete(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回路径
|
||||||
|
const toBack = (back) => {
|
||||||
|
let url = ''
|
||||||
|
switch (back) {
|
||||||
|
case 'stockIn':
|
||||||
|
// 入库单开单
|
||||||
|
url = '/pages/warehousing/stockIn/create'
|
||||||
|
break;
|
||||||
|
case 'stockOut':
|
||||||
|
// 出库单开单
|
||||||
|
url = ''
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let params = pathParams.value
|
||||||
|
delete params.backStr
|
||||||
|
delete params.flag
|
||||||
|
const query = objectToQuery(params)
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `${url}${query}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 选择:仓库/存储区
|
||||||
|
const onChecked = (val) => {
|
||||||
|
const flag = isWarehousing.value ? 'app_warehousing' : 'app_storageArea'
|
||||||
|
let infoChecked = uni.getStorageSync(flag);
|
||||||
|
if (!Array.isArray(infoChecked)) {
|
||||||
|
infoChecked = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
infoChecked = [{ ...val }]
|
||||||
|
uni.setStorageSync(flag, infoChecked);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回list
|
||||||
|
toBack(backStr.value)
|
||||||
|
|
||||||
|
}
|
||||||
|
onShow(() => {
|
||||||
|
pagingRef.value?.reload?.()
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.topSearch {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 999;
|
||||||
|
padding: 4rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.containerBox {
|
||||||
|
padding-top: 44px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.zp-l-text-rpx {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep.listBox {
|
||||||
|
.uni-list {
|
||||||
|
background-color: #F8F8FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-list-item {
|
||||||
|
margin-bottom: 1rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-list-item__container {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty {
|
||||||
|
color: #D3D3D3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
88
pages/components/DetailInfo.vue
Normal file
88
pages/components/DetailInfo.vue
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view>
|
||||||
|
<view class="detailInfo mb-2">
|
||||||
|
<view class="line title">
|
||||||
|
<p> {{ typeName + '单号' }}:{{ detailInfo?.billNo }}</p>
|
||||||
|
<span :style="getColor(detailInfo?.billType)">
|
||||||
|
{{ getBillType(detailInfo?.billType,detailInfo?.status) }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<p class="line content">仓库:
|
||||||
|
<span> {{ detailInfo?.warehouseName }}</span>
|
||||||
|
</p>
|
||||||
|
<p class="line content">存储区:
|
||||||
|
<span> {{ detailInfo?.areaName }}</span>
|
||||||
|
</p>
|
||||||
|
<p class="line content">开单时间:
|
||||||
|
<span>{{ formatDate(detailInfo?.createTime) }}</span>
|
||||||
|
</p>
|
||||||
|
<p class="line content" v-if="detailInfo?.inboundTime">{{ typeName + '时间' }} :
|
||||||
|
<span>{{ formatDate(detailInfo?.inboundTime) }}</span>
|
||||||
|
</p>
|
||||||
|
</view>
|
||||||
|
<view class="detailInfo mb-6">
|
||||||
|
<p class="line content">
|
||||||
|
<span class="grey" style="font-weight: 600;">详细备注:</span>
|
||||||
|
|
||||||
|
<span>{{ detailInfo?.billRemark || '-' }}</span>
|
||||||
|
</p>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 物料列表 -只读 -->
|
||||||
|
<view>
|
||||||
|
<material-list ref="materialRef" isEdit="3" :extendData="{ billType: detailInfo?.billType }"
|
||||||
|
:pathParams="{ billNo: detailInfo?.billNo }" backStr="stockInDetail"
|
||||||
|
:formData="{ material: detailInfo.itemList }" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { getBillType, formatDate, getColor } from '../until'
|
||||||
|
import { computed, toRefs } from 'vue';
|
||||||
|
import MaterialList from './MaterialList.vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// 查询列表类型 stockIn:入库 stockOut:出库
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
detailInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: {},
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
const { type, detailInfo } = toRefs(props)
|
||||||
|
const typeName = computed(() => type.value == 'stockIn' ? '入库单' : '出库单')
|
||||||
|
|
||||||
|
console.log(detailInfo, 'detailInfo');
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.line {
|
||||||
|
display: flex;
|
||||||
|
background-color: #fff;
|
||||||
|
align-items: center;
|
||||||
|
padding: 6rpx 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
97
pages/components/LineSteps.vue
Normal file
97
pages/components/LineSteps.vue
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<view class="step-container">
|
||||||
|
<view class="step-item" :class="{ done: index < current, active: index == current }"
|
||||||
|
v-for="(item, index) in stepList" :key="index">
|
||||||
|
<!-- 节点圆圈 -->
|
||||||
|
<view class="step-circle">{{ index + 1 }}</view>
|
||||||
|
<!-- 文字 -->
|
||||||
|
<view class="step-text">{{ item }}</view>
|
||||||
|
<!-- 连接线(最后一个不显示) -->
|
||||||
|
<view class="step-line" v-if="index !== stepList.length - 1"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
// 步骤列表
|
||||||
|
const stepList = ref(['创建', '审核', '绑定', '完成'])
|
||||||
|
// 当前进度(0开始)
|
||||||
|
const current = ref(2)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 整体容器 */
|
||||||
|
.step-container {
|
||||||
|
display: flex;
|
||||||
|
padding: 30rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 单个步骤 */
|
||||||
|
.step-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 节点圆圈 */
|
||||||
|
.step-circle {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #cdd4e0;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 24rpx;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 文字 */
|
||||||
|
.step-text {
|
||||||
|
margin-top: 12rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 连接线 */
|
||||||
|
.step-line {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
left: 50%;
|
||||||
|
width: 100%;
|
||||||
|
height: 4rpx;
|
||||||
|
background: #cdd4e0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============= 状态样式 ============= */
|
||||||
|
/* 已完成 */
|
||||||
|
.step-item.done .step-circle {
|
||||||
|
background: #07c160;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item.done .step-line {
|
||||||
|
background: #07c160;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item.done .step-text {
|
||||||
|
color: #07c160;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 当前激活 */
|
||||||
|
.step-item.active .step-circle {
|
||||||
|
background: #465bfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item.active .step-text {
|
||||||
|
color: #465bfd;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
281
pages/components/MaterialList.vue
Normal file
281
pages/components/MaterialList.vue
Normal file
@@ -0,0 +1,281 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 物料列表 - 添加物料 -->
|
||||||
|
<view class="materialList">
|
||||||
|
|
||||||
|
<view class="remarkLine">
|
||||||
|
<text>物料列表</text>
|
||||||
|
<uv-button type="primary" v-if="isEdit == 1" :plain="true" size="small" text="添加物料"
|
||||||
|
@click="toMaterial"></uv-button>
|
||||||
|
<view v-if="isEdit == 5" class="flex align-center justify-between">
|
||||||
|
<span class="f-12 mr-16 grey" style="font-size: 12px;" v-if="num > 0">
|
||||||
|
剩余<span style="color: red;">
|
||||||
|
{{ num }}
|
||||||
|
</span>种物料未生成唯一码
|
||||||
|
</span>
|
||||||
|
<uv-button type="primary" :plain="true" size="small" text="快速生成唯一码"
|
||||||
|
@click="toGenerateUniqueCodeQuickly"></uv-button>
|
||||||
|
</view>
|
||||||
|
<!-- <p class="btn-link" v-if="isEdit == 2" @click="toEdit">修改</p> -->
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 物料列表-->
|
||||||
|
<view class="material-list-container">
|
||||||
|
<uni-forms ref="materialFormRef" :modelValue="formData">
|
||||||
|
<view v-for="(item, idx) in formData.material" :key="item.id || idx" class="material-box"
|
||||||
|
@longpress="() => handleItemLongPress(item, index)">
|
||||||
|
<view class="material-item" v-if="`${item?.isDelete}` === '0'">
|
||||||
|
<!-- 标题 -->
|
||||||
|
<view class="title mb-2">
|
||||||
|
{{ item.materialName }} ({{ item.materialCode }})
|
||||||
|
</view>
|
||||||
|
<!-- 副标题:简称/型号/规格/类型 -->
|
||||||
|
<view class="subTitle mb-2">
|
||||||
|
<span v-if="item.materialShortName">{{ item.materialShortName }} / </span>
|
||||||
|
<span v-if="item.model">{{ item.model }} / </span>
|
||||||
|
<span v-if="item.specification">{{ item.specification }} / </span>
|
||||||
|
<span v-if="item.typeName">{{ item.typeName }}</span>
|
||||||
|
</view>
|
||||||
|
<!-- uniqueCode -->
|
||||||
|
<view class="uniqueCode mb-2">
|
||||||
|
<span class="f-12 " v-if="item.uniqueCode">唯一码:{{ item?.uniqueCode }}</span>
|
||||||
|
</view>
|
||||||
|
<!-- 数量 + 单位 -->
|
||||||
|
<view class="tag-row mb-2">
|
||||||
|
<span class="tag-error">{{ getTypeParentNames(item.typeParentNames) }}</span>
|
||||||
|
<view class="quantity-form">
|
||||||
|
<uni-forms-item :name="`material[${idx}].quantity`" label-width="0">
|
||||||
|
<uni-easyinput :disabled="!edit || isEdit == '5'"
|
||||||
|
v-model="formData.material[idx].quantity" type="number" :clearable="false"
|
||||||
|
placeholder="数量" />
|
||||||
|
</uni-forms-item>
|
||||||
|
<text class="unit">{{ item.unitName }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 库存状态 -->
|
||||||
|
<view class="flex justify-between mb-2 " v-if="isEdit == 3">
|
||||||
|
<p style="font-size: 13px;">
|
||||||
|
已入库:
|
||||||
|
<span style="color:green">{{ getStockQuantity(item, 'complete') }}</span>
|
||||||
|
</p>
|
||||||
|
<p style="font-size: 13px;">
|
||||||
|
剩余:
|
||||||
|
<span style="color:red">{{ getStockQuantity(item, 'remaining') }}</span>
|
||||||
|
</p>
|
||||||
|
</view>
|
||||||
|
<!-- 备注 -->
|
||||||
|
<view class="remark-row">
|
||||||
|
<uni-forms-item :name="`material[${idx}].remark`" label="备注:">
|
||||||
|
<uni-easyinput :disabled="!edit" v-model="formData.material[idx].remark" type="text"
|
||||||
|
:clearable="false" :inputBorder="false" placeholder="请填写备注信息" />
|
||||||
|
</uni-forms-item>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 空数据提示 -->
|
||||||
|
<view class="empty" v-if="!formData.material?.length">
|
||||||
|
暂无物料,请添加物料
|
||||||
|
</view>
|
||||||
|
</uni-forms>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 选择物料 -->
|
||||||
|
<uv-modal ref="modalRef" class="chooseModal" :title="none" :showConfirmButton="false" :showCancelButton="false">
|
||||||
|
<p class="title">请选择称重来源</p>
|
||||||
|
<p class="link" @click="toMaterialSelection('0')">无线液位计</p>
|
||||||
|
<p class="link" @click="toMaterialSelection('1')">手动输入</p>
|
||||||
|
|
||||||
|
</uv-modal>
|
||||||
|
|
||||||
|
<!-- 删除弹窗 -->
|
||||||
|
<view>
|
||||||
|
<uni-popup ref="alertDialog" type="center">
|
||||||
|
<uni-popup-dialog type="error" v-if="isDialog" cancelText="取消" confirmText="确认" title="是否需要删除该唯一码?"
|
||||||
|
@confirm="dialogConfirm" @close="dialogClose"></uni-popup-dialog>
|
||||||
|
</uni-popup>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { computed, onMounted, ref, toRefs } from 'vue';
|
||||||
|
import { assign, findIndex } from 'lodash';
|
||||||
|
import { getStockQuantity, objectToQuery } from '../until';
|
||||||
|
import { getTypeParentNames } from '../warehousing/uniqueCode/until';
|
||||||
|
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
formData: { type: Object, default: () => ({ material: [], remark: '' }), required: true },//物料信息
|
||||||
|
isEdit: { type: Boolean, default: true, required: true }, //编辑1 / 物料只读2 / 入库单只读3 /入库生成唯一码编辑4 /5数量不可编辑 备注可编辑
|
||||||
|
backStr: { type: String, default: '' }, //选择物料返回页面的标识
|
||||||
|
pathParams: { type: Object, default: {} }, //只读时传入对应的code、id
|
||||||
|
extendData: { type: Object, default: {} }, //其他额外参数
|
||||||
|
})
|
||||||
|
|
||||||
|
const { formData, isEdit, backStr, pathParams, extendData } = toRefs(props)
|
||||||
|
console.log(extendData, 'extendData==>');
|
||||||
|
|
||||||
|
//是否为编辑状态
|
||||||
|
const edit = computed(() => {
|
||||||
|
if (`${isEdit.value}` === '1') return '1';
|
||||||
|
else if (`${isEdit.value}` === '4') return '4';
|
||||||
|
else return false;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 删除:数据
|
||||||
|
const delItem = ref(null)
|
||||||
|
// 删除:开关
|
||||||
|
const alertDialog = ref(null)
|
||||||
|
// 删除:开关
|
||||||
|
const isDialog = ref(false)
|
||||||
|
const selectMaterialList = computed(() => extendData.value?.selectMaterialList)
|
||||||
|
const num = computed(() => selectMaterialList.value?.length || 0)
|
||||||
|
// 弹窗开关:入库单开单
|
||||||
|
const modalRef = ref()
|
||||||
|
|
||||||
|
// 按钮:添加物料
|
||||||
|
const toMaterial = () => {
|
||||||
|
if (backStr.value == 'stockIn') { // 入库单开单 - 添加物料可选择手输入/无线液位计
|
||||||
|
modalRef.value.open()
|
||||||
|
} else {
|
||||||
|
const path = objectToQuery({ ...pathParams.value, back: backStr?.value })
|
||||||
|
// 唯一码 - 编辑/新增
|
||||||
|
let url = '/pages/warehousing/uniqueCode/issueUniqueCode/materialSelection';
|
||||||
|
const value = uni.getStorageSync('app_material');
|
||||||
|
uni.setStorageSync('app_material', [{ ...value[0], uniqueCodeRemark: formData.value?.remark }]); // 将最新的唯一码备注写入缓存
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `${url}${path}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 添加物料弹窗: 入库单入库 时可选择手动/无线液
|
||||||
|
const toMaterialSelection = (type) => {
|
||||||
|
// 0无线液 1手动输入
|
||||||
|
let url = ''
|
||||||
|
const path = objectToQuery({ ...pathParams.value, back: backStr.value })
|
||||||
|
if (type === '1') {
|
||||||
|
url = '/pages/warehousing/uniqueCode/issueUniqueCode/materialSelection'
|
||||||
|
}
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `${url}${path}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 快速生成唯一码 -
|
||||||
|
const toGenerateUniqueCodeQuickly = () => {
|
||||||
|
const path = objectToQuery({ ...pathParams.value, back: 'inbound' })
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/warehousing/uniqueCode/issueUniqueCode/index${path}`
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
// 删除弹窗:显示 长按事件
|
||||||
|
const handleItemLongPress = (val) => {
|
||||||
|
alertDialog.value.open()
|
||||||
|
isDialog.value = true
|
||||||
|
delItem.value = val
|
||||||
|
}
|
||||||
|
// 删除弹窗:关闭
|
||||||
|
const dialogClose = () => {
|
||||||
|
alertDialog.value.close()
|
||||||
|
isDialog.value = false
|
||||||
|
}
|
||||||
|
// 删除弹窗:确认
|
||||||
|
const dialogConfirm = () => {
|
||||||
|
const idx = findIndex(formData.value.material, (i) => `${i.id}` === `${delItem.value.id}`)
|
||||||
|
assign(formData.value.material[idx], { isDelete: '1' });
|
||||||
|
uni.setStorageSync('app_material', formData.value.material)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getMaterialList = () => {
|
||||||
|
const params = formData.value?.material?.map((i) => ({
|
||||||
|
...i,
|
||||||
|
material: {
|
||||||
|
//? 这里的判断是为了区分 =详情带出的物料以及新增的物料 详情带出的物料有id以及materialId 新增物料id为物料id materialId无值
|
||||||
|
materialId: i.materialId ? i.materialId : i.id,
|
||||||
|
id: i.materialId ? i.id : null,
|
||||||
|
remark: i.remark,
|
||||||
|
quantity: i.quantity,
|
||||||
|
unitId: i.unitId,
|
||||||
|
isDelete: i?.isDelete,
|
||||||
|
uniqueCode: i?.uniqueCode
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
getMaterialList
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.remarkLine {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #fff;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 12px 15px;
|
||||||
|
margin-bottom: 2rpx;
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-link {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #3c9cff;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .uv-button {
|
||||||
|
height: 30px;
|
||||||
|
// line-height: 60rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-item {
|
||||||
|
padding: 12px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty {
|
||||||
|
text-align: center;
|
||||||
|
padding: 60rpx 0;
|
||||||
|
color: #999;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep.chooseModal {
|
||||||
|
.uv-modal__content {
|
||||||
|
display: block;
|
||||||
|
padding-top: 24rpx !important;
|
||||||
|
padding: 48rpx;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 16rpx 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
color: #999;
|
||||||
|
margin-top: 24rpx;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
107
pages/components/Navigation.vue
Normal file
107
pages/components/Navigation.vue
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 状态栏占位 -->
|
||||||
|
<view class="nav-placeholder" :style="{ height: navHeight + 'px' }"></view>
|
||||||
|
|
||||||
|
<view class="navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||||||
|
|
||||||
|
<view class="left" @click="goBack">
|
||||||
|
<uni-icons type="left" size="18" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 中间标题 -->
|
||||||
|
<view class="title">{{ title }}</view>
|
||||||
|
|
||||||
|
<!-- 右侧:父组件传入插槽 -->
|
||||||
|
<view class="right">
|
||||||
|
<slot name="right"></slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="content">
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
import { ref, onMounted, toRefs } from 'vue'
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
|
const props = defineProps({
|
||||||
|
title: { type: String, default: '' },
|
||||||
|
backUrl: { type: String, default: '' },
|
||||||
|
})
|
||||||
|
const statusBarHeight = ref(0)
|
||||||
|
const navHeight = ref(0)
|
||||||
|
const back = ref('')
|
||||||
|
const { backUrl, title } = toRefs(props)
|
||||||
|
onMounted(() => {
|
||||||
|
const res = uni.getSystemInfoSync()
|
||||||
|
statusBarHeight.value = res.statusBarHeight
|
||||||
|
navHeight.value = res.statusBarHeight + 44
|
||||||
|
})
|
||||||
|
// 接收id 且修改标题
|
||||||
|
onLoad(() => {
|
||||||
|
const pages = getCurrentPages()
|
||||||
|
if (pages.length >= 2) {
|
||||||
|
const prevPage = pages?.[pages.length - 2]
|
||||||
|
back.value = backUrl.value ? backUrl.value : prevPage.route
|
||||||
|
console.log(back.value, prevPage, pages, ' back.value');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
// 返回
|
||||||
|
const goBack = () => {
|
||||||
|
console.log(back.value, back.value);
|
||||||
|
|
||||||
|
if (back.value) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/${back.value}`,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.navigateBack()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.navbar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 70px;
|
||||||
|
background: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
z-index: 999;
|
||||||
|
// margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-txt {
|
||||||
|
margin-left: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
min-width: 60rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
186
pages/components/SearchList.vue
Normal file
186
pages/components/SearchList.vue
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
<!-- 查询列表 - 使用我的出库单/我的入库单 -->
|
||||||
|
<template>
|
||||||
|
<view class="content">
|
||||||
|
<view class="topSearch">
|
||||||
|
<uni-easyinput type="text" v-model="queryParams.keyword" prefixIcon="search" :inputBorder="false"
|
||||||
|
@iconClick="getList" placeholder="请输入搜索内容" />
|
||||||
|
</view>
|
||||||
|
<z-paging ref="pagingRef" class="containerBox" v-model="list" @query="getList">
|
||||||
|
<uni-list class="listBox">
|
||||||
|
<uni-list-item v-for="item in list" :key="item.id" clickable @click="onDetail(item)">
|
||||||
|
<template v-slot:body>
|
||||||
|
<view style="display: flex; flex-direction: column; width: 100%;">
|
||||||
|
<view class="line title">
|
||||||
|
<p> {{ typeName + '编号' }}:{{ item.billNo }}</p>
|
||||||
|
<span :style="getColor(item?.billType)">
|
||||||
|
{{ getBillType(item?.billType, item?.status) }}
|
||||||
|
</span>
|
||||||
|
</view>
|
||||||
|
<p class="line content">{{ typeName + '类型' }}:
|
||||||
|
<span> {{ getOrderType(item.status) }}</span>
|
||||||
|
</p>
|
||||||
|
<p class="line content">库位:
|
||||||
|
<span> {{ item.areaName }}</span>
|
||||||
|
</p>
|
||||||
|
<p class="line content">开单时间:
|
||||||
|
<span>{{ item.createTime }}</span>
|
||||||
|
</p>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</uni-list-item>
|
||||||
|
</uni-list>
|
||||||
|
</z-paging>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
import _, { includes } from 'lodash';
|
||||||
|
import { computed, toRefs, ref } from 'vue';
|
||||||
|
import { onShow } from "@dcloudio/uni-app";
|
||||||
|
import { stockList } from '../../api/stockIn';
|
||||||
|
import { getBillType, getColor } from '../until';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// 查询列表类型 stockIn:入库 stockIn-putAway:入库单入库 stockOut:出库
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
// 查询条件
|
||||||
|
query: {
|
||||||
|
type: Object,
|
||||||
|
default: {},
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
|
||||||
|
})
|
||||||
|
const { type, query } = toRefs(props)
|
||||||
|
const pagingRef = ref(null)
|
||||||
|
|
||||||
|
// 数据:列表
|
||||||
|
const list = ref([])
|
||||||
|
const typeName = computed(() => includes(type.value, 'stockIn') ? '入库单' : '出库单')
|
||||||
|
const getOrderType = () => {
|
||||||
|
if (includes(type.value, 'stockIn')) {
|
||||||
|
return '入库单入库'
|
||||||
|
} else {
|
||||||
|
return '出库单出库'
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 数据:关键字
|
||||||
|
const queryParams = ref({
|
||||||
|
keyword: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
pagingRef.value?.reload?.()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 点击:查看详情
|
||||||
|
const onDetail = (val) => {
|
||||||
|
if (_.includes(type.value, 'stockIn')) {
|
||||||
|
// pages/stockIn/detail
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/warehousing/stockIn/components/detail?billNo=${val.billNo}&type=${type.value}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// 数据:获取列表
|
||||||
|
const getList = (pageNo, pageSize) => {
|
||||||
|
queryParams.value.pageNum = pageNo
|
||||||
|
if (_.includes(type.value, 'stockIn')) {
|
||||||
|
stockList({ ...queryParams?.value, ...query?.value }).then(res => {
|
||||||
|
res.rows.forEach(e => {
|
||||||
|
e.showMore = false;
|
||||||
|
});
|
||||||
|
pagingRef.value.complete(res.rows)
|
||||||
|
}).catch(res => {
|
||||||
|
pagingRef.value.complete(false)
|
||||||
|
})
|
||||||
|
} else if (type.value == 'stockOut') {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.topSearch {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 999;
|
||||||
|
padding: 4rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.containerBox {
|
||||||
|
padding-top: 44px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.zp-l-text-rpx {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .listBox {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #F8F8FF;
|
||||||
|
|
||||||
|
.zp-l-text-rpx {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-list {
|
||||||
|
background-color: #F8F8FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-list-item {
|
||||||
|
margin-bottom: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-list-item__container {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line {
|
||||||
|
display: flex;
|
||||||
|
// justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
// border-bottom: 1px solid #eee;
|
||||||
|
padding: 12rpx 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty {
|
||||||
|
color: #D3D3D3;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #696969;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
144
pages/components/WarehousingInfo.vue
Normal file
144
pages/components/WarehousingInfo.vue
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
<!-- 获取仓库数据 -->
|
||||||
|
<template>
|
||||||
|
<view class="content">
|
||||||
|
<uv-form ref="formRef" class="form" :model="formData" label-width="150rpx">
|
||||||
|
<!-- 仓库 -->
|
||||||
|
<uv-form-item label="仓库" prop="warehouse">
|
||||||
|
<u-cell @click="onClick('warehouse')">
|
||||||
|
<view slot="title" class="u-slot-title">
|
||||||
|
<text class="u-cell-text" v-if="formData?.warehousing?.[0]?.deptName">
|
||||||
|
{{ formData?.warehousing?.[0].deptName }}
|
||||||
|
</text>
|
||||||
|
<text class="placeholder" v-else> 请选择仓库</text>
|
||||||
|
<uni-icons type="right" size="10" />
|
||||||
|
</view>
|
||||||
|
</u-cell>
|
||||||
|
</uv-form-item>
|
||||||
|
<!-- 存储区 -->
|
||||||
|
<uv-form-item label="存储区" prop="storageArea">
|
||||||
|
<u-cell @click="onClick('storageArea')">
|
||||||
|
<view slot="title" class="u-slot-title">
|
||||||
|
<text class="u-cell-text" v-if="formData?.storageArea?.[0]?.deptName">
|
||||||
|
{{ formData?.storageArea?.[0].deptName }}
|
||||||
|
</text>
|
||||||
|
<text class="placeholder" v-else> 请选择存储区</text>
|
||||||
|
<uni-icons type="right" size="10" />
|
||||||
|
</view>
|
||||||
|
</u-cell>
|
||||||
|
</uv-form-item>
|
||||||
|
<!-- 备注 -->
|
||||||
|
<uv-form-item label="备注">
|
||||||
|
<uv-input v-model="formData.remark" placeholder="请输入备注" align="right" border="none" />
|
||||||
|
</uv-form-item>
|
||||||
|
</uv-form>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, toRefs } from 'vue';
|
||||||
|
import { objectToQuery } from '../until';
|
||||||
|
import { onShow } from "@dcloudio/uni-app";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// 数据:仓库信息
|
||||||
|
warehouseInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
// 数据:路径参数
|
||||||
|
pathParams: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const { warehouseInfo, pathParams } = toRefs(props)
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = ref({ remark: '', warehousing: '', storageArea: '' })
|
||||||
|
|
||||||
|
// 赋值:更新列表值
|
||||||
|
const setFormData = (d) => {
|
||||||
|
if (!d) return;
|
||||||
|
formData.value = d
|
||||||
|
}
|
||||||
|
// 渲染:更新列表值
|
||||||
|
onShow(() => {
|
||||||
|
setFormData(warehouseInfo.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 点击事件:选择仓库/选择存储区
|
||||||
|
const onClick = (type) => {
|
||||||
|
uni.setStorageSync('app_billRemark', formData.value.remark)
|
||||||
|
|
||||||
|
let query = { ...pathParams.value, backStr: 'stockIn' }
|
||||||
|
if (type == 'warehouse') {
|
||||||
|
query = objectToQuery({ ...query, flag: 'warehousing' })
|
||||||
|
} else if (type == 'storageArea') {
|
||||||
|
query = objectToQuery({ ...query, flag: 'storageArea' })
|
||||||
|
}
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/warehousing/toChooseList${query}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//暴露:向父组件暴露 - 暂时没用
|
||||||
|
defineExpose({
|
||||||
|
getWarehousingInfo: () => {
|
||||||
|
return { ...formData.value }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
::v-deep .form {
|
||||||
|
// background-color: #fff;
|
||||||
|
padding: 0 0 12rpx 0;
|
||||||
|
|
||||||
|
.uv-input__content {
|
||||||
|
|
||||||
|
.uv-input__content__field-wrapper__field {
|
||||||
|
text-align: right !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.uv-form-item__body {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 12rpx;
|
||||||
|
margin-bottom: 2rpx;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uv-form-item__body__left__content__label {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uv-line {
|
||||||
|
border-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uv-form-item__body__right__content__slot {
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uv-cell__body {
|
||||||
|
padding: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-icons {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.u-slot-title {
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder {
|
||||||
|
color: rgb(192, 196, 204);
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<!-- 底部导航栏:首页 -->
|
||||||
<template>
|
<template>
|
||||||
<view class="content">
|
<view class="content">
|
||||||
首页
|
首页
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<!-- 底部导航栏:智能 -->
|
||||||
<template>
|
<template>
|
||||||
<view class="content">
|
<view class="content">
|
||||||
智能
|
智能
|
||||||
|
|||||||
@@ -32,7 +32,8 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { onLoad } from "@dcloudio/uni-app";
|
import {removeStorage} from '../until';
|
||||||
|
|
||||||
import { userLogin, getCodeImg, getInfo } from "@/api/login"
|
import { userLogin, getCodeImg, getInfo } from "@/api/login"
|
||||||
|
|
||||||
const formModel = ref({
|
const formModel = ref({
|
||||||
@@ -96,6 +97,7 @@ const submit = () => {
|
|||||||
uni.setStorageSync('app_user', user.user)
|
uni.setStorageSync('app_user', user.user)
|
||||||
uni.setStorageSync('app_roles', user.roles)
|
uni.setStorageSync('app_roles', user.roles)
|
||||||
uni.setStorageSync('app_permissions', user.permissions)
|
uni.setStorageSync('app_permissions', user.permissions)
|
||||||
|
removeStorage()
|
||||||
uni.switchTab({
|
uni.switchTab({
|
||||||
url: "/pages/index/index"
|
url: "/pages/index/index"
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<!-- 底部导航栏:我的 -->
|
||||||
<template>
|
<template>
|
||||||
<view class="content">
|
<view class="content">
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
</uni-list>
|
</uni-list>
|
||||||
</view>
|
</view>
|
||||||
<uni-popup ref="popupRef" type="center" background-color="#fff" borderRadius="8px">
|
<uni-popup ref="popupRef" type="center" background-color="#fff" borderRadius="8px">
|
||||||
<view class="popup-wrap" style="width: 400rpx; ">
|
<view class="popup-wrap" style="width: 200rpx; ">
|
||||||
<view class="popup-body">
|
<view class="popup-body">
|
||||||
<p>确定退出登录吗?</p>
|
<p>确定退出登录吗?</p>
|
||||||
<view class="popup-btn">
|
<view class="popup-btn">
|
||||||
@@ -128,7 +129,7 @@ getUserInfo();
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
.uv-button-wrapper{
|
.uv-button-wrapper{
|
||||||
width: 48%;
|
width: 40%;
|
||||||
margin-left: 8rpx;
|
margin-left: 8rpx;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,242 +0,0 @@
|
|||||||
<!-- 唯一码发放页面 -->
|
|
||||||
<template>
|
|
||||||
<view class="content">
|
|
||||||
<view class="remarkLine">
|
|
||||||
<span>备注:</span>
|
|
||||||
<uni-easyinput type="text" v-model="formData.remark" :inputBorder="false" placeholder="请输入备注" />
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 物料列表 - 添加物料 -->
|
|
||||||
<view class="remarkLine">
|
|
||||||
<p>物料列表</p>
|
|
||||||
<uv-button type="primary" :plain="true" size="small" text="添加物料" @click="toMaterial"></uv-button>
|
|
||||||
|
|
||||||
</view>
|
|
||||||
<view>
|
|
||||||
<uni-forms ref="materialFormRef" :modelValue="formData.material" class="form">
|
|
||||||
<view v-for="(item, idx) in materialList" :key="item.id" class="material-card"
|
|
||||||
style="padding: 24rpx; margin-bottom: 16rpx;">
|
|
||||||
<view style="display: flex; flex-direction: column; width: 100%;">
|
|
||||||
<!-- 标题行 -->
|
|
||||||
<view class="title">{{ item.materialName }} ({{ item.materialCode }})</view>
|
|
||||||
|
|
||||||
<!--小标题行 简称/型号/规格/类型 -->
|
|
||||||
<view class="subTitle">
|
|
||||||
<span v-if="item.materialShortName">{{ item.materialShortName }} / </span>
|
|
||||||
<span v-if="item.model">{{ item.model }} / </span>
|
|
||||||
<span v-if="item.specification">{{ item.specification }} / </span>
|
|
||||||
<span v-if="item.typeName">{{ item.typeName }} </span>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 数量行 -->
|
|
||||||
<view class="tag">
|
|
||||||
<uni-tag :text="getTypeParentNames(item.typeParentNames)" type="error" />
|
|
||||||
<p class="tag-form">
|
|
||||||
<uni-forms-item :name="`material.${idx}.quantity`">
|
|
||||||
<uni-easyinput v-model="formData.material[idx].quantity" type="number"
|
|
||||||
:clearable="false" />
|
|
||||||
</uni-forms-item>
|
|
||||||
<span style=" margin-left: 8rpx; width: 16px;">{{ item.unitName }}</span>
|
|
||||||
</p>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 备注行 -->
|
|
||||||
<view class="remark">
|
|
||||||
<uni-forms-item :name="`material.${idx}.remark`" label="备注:">
|
|
||||||
<uni-easyinput type="text" v-model="formData.material[idx].remark" :clearable="false"
|
|
||||||
:inputBorder="false" placeholder="请填写备注信息" />
|
|
||||||
</uni-forms-item>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</uni-forms>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<button class="bottom-btn" type="primary" @click="handleSubmit">提交</button>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<script setup>
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { getTypeParentNames } from '../until';
|
|
||||||
import { addUniqueCode, editUniqueCode } from '@/api/uniqueCode'
|
|
||||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
|
||||||
|
|
||||||
const formData = ref({
|
|
||||||
remark: '',
|
|
||||||
material: []
|
|
||||||
})
|
|
||||||
// 物料列表
|
|
||||||
const materialList = ref([])
|
|
||||||
const materialFormRef = ref([])
|
|
||||||
|
|
||||||
// 路径参数
|
|
||||||
const pathParams = ref('')
|
|
||||||
|
|
||||||
// 选择物料列表
|
|
||||||
const toMaterial = () => {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/uniqueCode/issueUniqueCode/materialSelection'
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
// 接收路径参数 - 修改标题
|
|
||||||
onLoad((options) => {
|
|
||||||
pathParams.value = options
|
|
||||||
})
|
|
||||||
onShow(() => {
|
|
||||||
if (pathParams.value.code) {
|
|
||||||
uni.setNavigationBarTitle({ title: pathParams.value.code })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 创建/编辑 唯一码
|
|
||||||
const handleSubmit = () => {
|
|
||||||
materialFormRef.value.validate().then(res => {
|
|
||||||
let params = {
|
|
||||||
...formData.value,
|
|
||||||
material: {
|
|
||||||
materialId: formData.value.material[0].id,
|
|
||||||
remark: formData.value.material[0].remark,
|
|
||||||
quantity: formData.value.material[0].quantity,
|
|
||||||
unitId: formData.value.material[0].unitId,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pathParams.value.id) {
|
|
||||||
params.id = pathParams.value.id;
|
|
||||||
params.material.id = pathParams.value.materialId;
|
|
||||||
params.material.materialId = formData.value.material[0].materialId;
|
|
||||||
editUniqueCode(params).then((response) => {
|
|
||||||
if (response.code == 200) {
|
|
||||||
uni.showToast({
|
|
||||||
title: '唯一码编辑成功',
|
|
||||||
mask: true,
|
|
||||||
icon: 'success',
|
|
||||||
})
|
|
||||||
uni.navigateTo({
|
|
||||||
url: `/pages/uniqueCode/myUniqueCode/detail?id=${pathParams.value.id}&code=${pathParams.value.code}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
addUniqueCode(params).then((response) => {
|
|
||||||
if (response.code == 200) {
|
|
||||||
uni.showToast({
|
|
||||||
title: '唯一码创建成功',
|
|
||||||
mask: true,
|
|
||||||
icon: 'success',
|
|
||||||
})
|
|
||||||
uni.switchTab({
|
|
||||||
url: "/pages/warehousing/index"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取缓存内的物料列表
|
|
||||||
const getMaterialList = () => {
|
|
||||||
uni.getStorage({
|
|
||||||
key: 'app_material',
|
|
||||||
success: ({ data }) => {
|
|
||||||
materialList.value = data
|
|
||||||
formData.value.material = data
|
|
||||||
formData.value.remark = data?.[0]?.uniqueCodeRemark
|
|
||||||
console.log(formData);
|
|
||||||
},
|
|
||||||
fail: (error) => { }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
getMaterialList();
|
|
||||||
</script>
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.remarkLine {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background-color: #fff;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 8rpx 24rpx;
|
|
||||||
margin-bottom: 8rpx;
|
|
||||||
min-height: 40rpx;
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 14px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .uv-button {
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .form {
|
|
||||||
.title {
|
|
||||||
color: #424242;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
.uni-tag {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: calc(25px - 6px);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-form {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.uni-forms-item {
|
|
||||||
margin-bottom: 0;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.uni-easyinput__content,
|
|
||||||
.uni-easyinput__content-input {
|
|
||||||
height: 25px;
|
|
||||||
width: 80px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.remark {
|
|
||||||
.uni-forms-item {
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-top: 16rpx;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.uni-forms-item__label {
|
|
||||||
color: #212121;
|
|
||||||
height: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.uni-easyinput__content-input {
|
|
||||||
height: 40rpx;
|
|
||||||
|
|
||||||
.uni-input-wrapper {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.uni-input-placeholder {
|
|
||||||
text-align: right;
|
|
||||||
font-size: 13px;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
<!-- 物料选择 -->
|
|
||||||
<template>
|
|
||||||
<view class="content">
|
|
||||||
<view class="topSearch">
|
|
||||||
<uni-easyinput type="text" v-model="queryParams.keyword" prefixIcon="search" :inputBorder="false"
|
|
||||||
@iconClick="getMaterialList" placeholder="请输入搜索内容" />
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 物料列表 -->
|
|
||||||
<z-paging ref="pagingRef" class="containerBox" v-model="materialList" @query="getMaterialList">
|
|
||||||
<uni-list>
|
|
||||||
<uni-list-item v-for="item in materialList" :key="item.id" clickable class="material-card"
|
|
||||||
@click="onMaterial(item)">
|
|
||||||
<template v-slot:body>
|
|
||||||
<p style="display: flex; flex-direction: column; width: 100%;">
|
|
||||||
<p class="title">{{ item.materialName }} ({{ item.materialCode }})</p>
|
|
||||||
<p class="subTitle">
|
|
||||||
<!-- 简称/型号/规格/类型 -->
|
|
||||||
<span v-if="item.materialShortName">{{ item.materialShortName }} / </span>
|
|
||||||
<span v-if="item.model">{{ item.model }} / </span>
|
|
||||||
<span v-if="item.specification">{{ item.specification }} / </span>
|
|
||||||
<span v-if="item.typeName">{{ item.typeName }} </span>
|
|
||||||
</p>
|
|
||||||
<p class="tag">
|
|
||||||
<uni-tag :text="getTypeParentNames(item.typeParentNames)" type="error" />
|
|
||||||
<p>单位:{{ item.unitName }}</p>
|
|
||||||
</p>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</uni-list-item>
|
|
||||||
</uni-list>
|
|
||||||
</z-paging>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<script setup>
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { getMaterial } from '@/api/uniqueCode'
|
|
||||||
import { onShow } from "@dcloudio/uni-app";
|
|
||||||
import { getTypeParentNames } from '../until';
|
|
||||||
|
|
||||||
const queryParams = ref({
|
|
||||||
keyword:''
|
|
||||||
})
|
|
||||||
|
|
||||||
const pagingRef = ref(null)
|
|
||||||
const materialList = ref([])
|
|
||||||
|
|
||||||
// 获取列表
|
|
||||||
const getMaterialList = () => {
|
|
||||||
getMaterial(queryParams.value).then(res => {
|
|
||||||
res.rows.forEach(e => {
|
|
||||||
e.showMore = false;
|
|
||||||
});
|
|
||||||
pagingRef.value.complete(res.rows)
|
|
||||||
}).catch(res => {
|
|
||||||
pagingRef.value.complete(false)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onShow(() => {
|
|
||||||
pagingRef.value?.reload?.()
|
|
||||||
})
|
|
||||||
|
|
||||||
// 搜索物料
|
|
||||||
const handleSearch = () => {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 选择物料
|
|
||||||
const onMaterial = (val) => {
|
|
||||||
let materialChecked = uni.getStorageSync('app_material');
|
|
||||||
if (!Array.isArray(materialChecked)) {
|
|
||||||
materialChecked = [];
|
|
||||||
}
|
|
||||||
const idx = materialChecked?.findIndex((i) => i.id === val.id)
|
|
||||||
if (idx != -1) {
|
|
||||||
//! 现在仅允许添加一条物料打印一个唯一码 但保留可添加多个
|
|
||||||
// uni.showToast({
|
|
||||||
// title: '该物料已添加,请勿重复添加!',
|
|
||||||
// mask: true,
|
|
||||||
// icon: 'none',
|
|
||||||
// })
|
|
||||||
} else {
|
|
||||||
if (val) {
|
|
||||||
// materialChecked = [...materialChecked, { ...val, quantity: 1 }];
|
|
||||||
materialChecked = [{ ...val, quantity: 1 }]
|
|
||||||
uni.setStorageSync('app_material', materialChecked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/uniqueCode/issueUniqueCode/index'
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.topSearch {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 999;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.containerBox {
|
|
||||||
// padding: 0 12rpx;
|
|
||||||
padding-top: 60px;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.zp-l-text-rpx {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
<template>
|
|
||||||
|
|
||||||
|
|
||||||
<view class="top">
|
|
||||||
|
|
||||||
<img style="width: 80rpx; height: 80rpx;" src="../../../static//logo/logo.jpg" />
|
|
||||||
|
|
||||||
<svg id="barcodeSvg" ref="barcodeRef"></svg>
|
|
||||||
|
|
||||||
</view>
|
|
||||||
<view class="content mt-16">
|
|
||||||
<p>物料:
|
|
||||||
<span>{{ material?.materialName }}</span>
|
|
||||||
<span v-if="material?.quantity">x {{ material?.quantity }}</span>
|
|
||||||
</p>
|
|
||||||
<p>描述:
|
|
||||||
<span v-if="material?.description">{{ material?.description || '-' }}</span>
|
|
||||||
<span v-else>
|
|
||||||
<span v-if="material?.materialShortName">{{ material?.materialShortName }} / </span>
|
|
||||||
<span v-if="material?.model">{{ material?.model }} / </span>
|
|
||||||
<span v-if="material?.specification">{{ material?.specification }} / </span>
|
|
||||||
<span v-if="material?.typeName">{{ material?.typeName }} </span>
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
<view class="top">
|
|
||||||
<p>备注:
|
|
||||||
<!-- 简称/型号/规格/物料类型 -->
|
|
||||||
<span>{{ material?.qrCodeMark || '' }}</span>
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<img :src="qrCode" class="qrcode" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { onMounted, computed } from 'vue';
|
|
||||||
import JsBarcode from 'jsbarcode'
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
detail: {
|
|
||||||
type: Object,
|
|
||||||
default: null,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 条形码容器
|
|
||||||
console.log(props.detail, 'props.detail');
|
|
||||||
|
|
||||||
// 二维码
|
|
||||||
const qrCode = computed(() => props.detail?.[0]?.qrCode);
|
|
||||||
// 物料数据
|
|
||||||
const material = computed(() => props.detail?.[0]);
|
|
||||||
// 条形码
|
|
||||||
const barcodeValue = computed(() => props.detail?.[0]?.code);
|
|
||||||
const generateBarcode = () => {
|
|
||||||
const svg = document.getElementById('barcodeSvg')
|
|
||||||
// SVG渲染:直接调用JsBarcode,无需清空(会自动替换内容)
|
|
||||||
JsBarcode(svg, barcodeValue.value, {
|
|
||||||
format: 'CODE128', // 常用的CODE128格式(支持任意字符)
|
|
||||||
width: 3,
|
|
||||||
height: 80,
|
|
||||||
displayValue: false,
|
|
||||||
margin: 10 // 条形码四周留白
|
|
||||||
})
|
|
||||||
}
|
|
||||||
onMounted(generateBarcode)
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.qrcode {
|
|
||||||
width: 120rpx;
|
|
||||||
height: 120rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
p {
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 14px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,292 +0,0 @@
|
|||||||
<!-- 唯一码详情 -->
|
|
||||||
<template>
|
|
||||||
<uv-skeletons :loading="loading" :skeleton="skeleton">
|
|
||||||
<view class=" content">
|
|
||||||
<!-- 唯一码展示 -->
|
|
||||||
<uni-list>
|
|
||||||
<uni-list-item v-for="item in uniqueCodeList" :key="item.id" clickable class="material-card">
|
|
||||||
<template v-slot:body>
|
|
||||||
<p style="display: flex; flex-direction: column; width: 100%;">
|
|
||||||
<!-- 编码、状态行 -->
|
|
||||||
<view class="flex-center">
|
|
||||||
<p class="title">编号:{{ item.code }}</p>
|
|
||||||
<p class="status">{{ getStatusName(item.status) }}</p>
|
|
||||||
</view>
|
|
||||||
<!-- 内容行 -->
|
|
||||||
<view class="text ">
|
|
||||||
<p>RFID:
|
|
||||||
<span v-if="item.rfidCode">{{ item.remark }}</span>
|
|
||||||
<span v-else style="color: #999;">未绑定RFID</span>
|
|
||||||
</p>
|
|
||||||
<p>生成时间:
|
|
||||||
<span>{{ item?.createTime }}</span>
|
|
||||||
</p>
|
|
||||||
<!-- 备注行-->
|
|
||||||
<view class="flex-center qrCode">
|
|
||||||
<p>备注:
|
|
||||||
<span v-if="item.remark">{{ item.remark }}</span>
|
|
||||||
<span v-else style="color: #999;">未填写</span>
|
|
||||||
</p>
|
|
||||||
<view @click="toViewQrCode">
|
|
||||||
<uv-image src="../../../static/qrcode.png" width="40rpx" height="40rpx"
|
|
||||||
style="margin-top:10rpx" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</p>
|
|
||||||
</template>
|
|
||||||
</uni-list-item>
|
|
||||||
</uni-list>
|
|
||||||
<!-- 物料列表 -->
|
|
||||||
<view class="remarkLine">
|
|
||||||
<p>物料列表</p>
|
|
||||||
<p class="btn-link" @click="toEdit">修改</p>
|
|
||||||
</view>
|
|
||||||
<view>
|
|
||||||
<uni-forms ref="materialFormRef" :modelValue="materialList" class="form">
|
|
||||||
<view v-for="(item, idx) in materialList" :key="item.id" class="material-card"
|
|
||||||
style="padding: 24rpx; margin-bottom: 16rpx;">
|
|
||||||
<view style="display: flex; flex-direction: column; width: 100%;">
|
|
||||||
<!-- 标题行 -->
|
|
||||||
<view class="title">{{ item.materialName }} ({{ item.materialCode }})</view>
|
|
||||||
|
|
||||||
<!--小标题行 简称/型号/规格/类型 -->
|
|
||||||
<view class="subTitle">
|
|
||||||
<span v-if="item.materialShortName">{{ item.materialShortName }} / </span>
|
|
||||||
<span v-if="item.model">{{ item.model }} / </span>
|
|
||||||
<span v-if="item.specification">{{ item.specification }} / </span>
|
|
||||||
<span v-if="item.typeName">{{ item.typeName }} </span>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 数量行 -->
|
|
||||||
<view class="tag">
|
|
||||||
<uni-tag :text="getTypeParentNames(item.typeParentNames) || ''" type="error" />
|
|
||||||
<p class="tag-form">
|
|
||||||
<uni-forms-item :name="`material.${idx}.quantity`">
|
|
||||||
<uni-easyinput v-model="materialList[idx].quantity" :disabled="true"
|
|
||||||
type="number" :clearable="false" />
|
|
||||||
</uni-forms-item>
|
|
||||||
<span style=" margin-left: 8rpx; width: 16px;">{{ item.unitName }}</span>
|
|
||||||
</p>
|
|
||||||
</view>
|
|
||||||
<!-- 备注行 -->
|
|
||||||
<view class="remark">
|
|
||||||
<uni-forms-item :name="`material.${idx}.remark`" label="备注:">
|
|
||||||
<uni-easyinput type="text" v-model="materialList[idx].remark"
|
|
||||||
:disabled="true" :clearable="false" :inputBorder="false"
|
|
||||||
placeholder="请填写备注信息" />
|
|
||||||
</uni-forms-item>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</uni-forms>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 底部按钮 -->
|
|
||||||
<view class="bottom">
|
|
||||||
<uv-button type="primary" text="唯一码打印"></uv-button>
|
|
||||||
<uv-button type="success" text="溯源" @click="toTraceability"></uv-button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</uv-skeletons>
|
|
||||||
<uv-modal ref="modalRef" :title="none" class="qrCodeModal" width="480rpx" :showConfirmButton="false">
|
|
||||||
<qr-code-modal :detail="materialList" />
|
|
||||||
</uv-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
|
||||||
import { detailUniqueCode } from '@/api/uniqueCode'
|
|
||||||
import { getTypeParentNames, getStatusName, getDetail } from '../until';
|
|
||||||
import QrCodeModal from './QrCodeModal.vue';
|
|
||||||
|
|
||||||
const modalRef = ref()
|
|
||||||
// 路径参数
|
|
||||||
const pathParams = ref('')
|
|
||||||
// 物料列表数组
|
|
||||||
const materialList = ref([])
|
|
||||||
// 唯一码数组
|
|
||||||
const uniqueCodeList = ref([])
|
|
||||||
// 详情数据
|
|
||||||
const detail = ref([])
|
|
||||||
// 骨架屏开关
|
|
||||||
const loading = ref(true)
|
|
||||||
// 骨架屏样式
|
|
||||||
const skeleton = [{
|
|
||||||
type: 'line',
|
|
||||||
num: 3,
|
|
||||||
gap: '20rpx',
|
|
||||||
style: ['width: 200rpx;marginBottom: 50rpx;marginTop:50rpx;padding:24rpx', 'height: 100rpx;', 'width: 500rpx;'],
|
|
||||||
}]
|
|
||||||
const toViewQrCode = () => {
|
|
||||||
modalRef.value.open()
|
|
||||||
|
|
||||||
}
|
|
||||||
// 详情:唯一码
|
|
||||||
const getDetailInfo = () => {
|
|
||||||
detailUniqueCode({ id: pathParams.value.id }).then((res) => {
|
|
||||||
if (res.code == 200) {
|
|
||||||
// ! 写成数组原因 为了适应可多个物料生成唯一码
|
|
||||||
materialList.value = [{ ...res.data.material, ...getDetail(res.data.material.wornMaterial), qrCode: res.data.qrCode, code: res.data.code, qrCodeMark: res.data.remark }]
|
|
||||||
uniqueCodeList.value = [res.data]
|
|
||||||
|
|
||||||
} else {
|
|
||||||
materialList.value = []
|
|
||||||
uniqueCodeList.value = []
|
|
||||||
uni.showToast({ title: '暂无数据', icon: 'none' })
|
|
||||||
}
|
|
||||||
loading.value = false
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改:唯一码的物料信息
|
|
||||||
const toEdit = () => {
|
|
||||||
uni.setStorageSync('app_material', [{ ...materialList.value?.[0], uniqueCodeRemark: uniqueCodeList.value?.[0].remark }]);
|
|
||||||
uni.navigateTo({
|
|
||||||
url: `/pages/uniqueCode/issueUniqueCode/index?code=${pathParams.value.code}&id=${pathParams.value.id}&materialId=${materialList.value?.[0].id}`,
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
// 溯源
|
|
||||||
const toTraceability = () => {
|
|
||||||
|
|
||||||
}
|
|
||||||
// 接收id 且修改标题
|
|
||||||
onLoad((options) => {
|
|
||||||
if (!options.id) {
|
|
||||||
loading.value = false
|
|
||||||
uni.showToast({ title: '参数错误,无唯一码ID', icon: 'none' })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
pathParams.value = options
|
|
||||||
getDetailInfo()
|
|
||||||
})
|
|
||||||
onShow(() => {
|
|
||||||
uni.setNavigationBarTitle({ title: pathParams.value.code })
|
|
||||||
})
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.remarkLine {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background-color: #fff;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 8rpx 24rpx;
|
|
||||||
margin-bottom: 4rpx;
|
|
||||||
min-height: 40rpx;
|
|
||||||
margin-top: 16rpx;
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 14px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-link {
|
|
||||||
font-weight: 500;
|
|
||||||
color: #3c9cff;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .form {
|
|
||||||
.title {
|
|
||||||
color: #424242;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
.uni-tag {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: calc(25px - 6px);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-form {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.uni-forms-item {
|
|
||||||
margin-bottom: 0;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.uni-easyinput__content,
|
|
||||||
.uni-easyinput__content-input {
|
|
||||||
height: 25px;
|
|
||||||
width: 80px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.remark {
|
|
||||||
.uni-forms-item {
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-top: 16rpx;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.is-disabled {
|
|
||||||
background-color: #fff !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.uni-forms-item__label {
|
|
||||||
color: #212121;
|
|
||||||
height: 40rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.uni-easyinput__content-input {
|
|
||||||
height: 40rpx;
|
|
||||||
|
|
||||||
.uni-input-wrapper {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.uni-input-placeholder {
|
|
||||||
text-align: right;
|
|
||||||
font-size: 13px;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.uni-input-input {
|
|
||||||
color: #616161
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 底部按钮
|
|
||||||
.bottom {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
height: 60rpx;
|
|
||||||
font-size: 14px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.uv-button-wrapper {
|
|
||||||
width: 50%;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep.qrCodeModal {
|
|
||||||
.uv-modal__content {
|
|
||||||
display: block;
|
|
||||||
padding: 24rpx;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
123
pages/until.js
Normal file
123
pages/until.js
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
import dayjs from "dayjs";
|
||||||
|
import numeral from "numeral";
|
||||||
|
// 订单状态
|
||||||
|
// 0=入库申请,1=入库成功,2=出库申请,3=出库成功,4=作废
|
||||||
|
const billTypeMenu = [
|
||||||
|
{
|
||||||
|
value: "0",
|
||||||
|
label: "入库单已提交",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "1",
|
||||||
|
label: "已完成",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "2",
|
||||||
|
label: "出库单已提交",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "3",
|
||||||
|
label: "已完成",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "4",
|
||||||
|
label: "已取消",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// 订单状态为0时 再查一次
|
||||||
|
const billStatueMenu = [
|
||||||
|
{
|
||||||
|
value: "0",
|
||||||
|
label: "入库单已提交",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "1",
|
||||||
|
label: "全部入库",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "2",
|
||||||
|
label: "物料部分入库",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
// 物料状态
|
||||||
|
const materialType = [
|
||||||
|
{
|
||||||
|
value: "0",
|
||||||
|
label: "未提交",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "1",
|
||||||
|
label: "已提交",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// 入/出库单状态的label
|
||||||
|
export const getBillType = (val, status) => {
|
||||||
|
if (val === "0") {
|
||||||
|
return billStatueMenu.find((i) => i.value == `${status}`)?.label;
|
||||||
|
}
|
||||||
|
return billTypeMenu.find((i) => i.value == `${val}`)?.label;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 获取出入库单的状态以及tag颜色
|
||||||
|
export const getColor = (val) => {
|
||||||
|
if (val == "0" || val == "2") {
|
||||||
|
return "color:#B8B8B8;font-weight:500;font-size:12px;";
|
||||||
|
} else if (val == "1" || val == "3") {
|
||||||
|
return "color:green;font-weight:500;font-size:12px;";
|
||||||
|
} else {
|
||||||
|
return "color:red;font-weight:500;font-size:12px;";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 时间格式化
|
||||||
|
export const formatDate = (t, fmt = "YYYY-MM-DD HH:mm:ss") =>
|
||||||
|
t ? dayjs(t).format(fmt) : "-";
|
||||||
|
|
||||||
|
// 数字格式化
|
||||||
|
export const formatNum = (num, fmt = "0.00") =>
|
||||||
|
num ? numeral(num).format(fmt) : "-";
|
||||||
|
|
||||||
|
// 入库单/出库单:获取已入库、出库数量
|
||||||
|
// item:此列数据 type:已入库、剩余数量
|
||||||
|
export const getStockQuantity = (item, type) => {
|
||||||
|
const num = item.quantity;
|
||||||
|
const status = item.status;
|
||||||
|
// 未入库
|
||||||
|
if (status == "0") {
|
||||||
|
if (type == "complete") {
|
||||||
|
return "0.000";
|
||||||
|
} else {
|
||||||
|
return formatNum(num, "0.00");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (type == "complete") {
|
||||||
|
return formatNum(num, "0.000");
|
||||||
|
} else {
|
||||||
|
return "0.00";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 清楚缓存 - 将所有需要清楚的缓存写入此处不要写登录信息
|
||||||
|
export const removeStorage = () => {
|
||||||
|
uni.removeStorageSync("app_warehousing");
|
||||||
|
uni.removeStorageSync("app_storageArea");
|
||||||
|
uni.removeStorageSync("app_billRemark");
|
||||||
|
uni.removeStorageSync("app_material");
|
||||||
|
uni.removeStorageSync("app_material_select_list");
|
||||||
|
};
|
||||||
|
|
||||||
|
// 对象转 URL 查询字符串 ?a=1&b=2
|
||||||
|
export const objectToQuery = (params) => {
|
||||||
|
if (!params || Object.keys(params).length === 0) return "";
|
||||||
|
|
||||||
|
const query = Object.entries(params)
|
||||||
|
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
|
||||||
|
.join("&");
|
||||||
|
|
||||||
|
return "?" + query;
|
||||||
|
};
|
||||||
147
pages/warehousing/StockIn/components/detail.vue
Normal file
147
pages/warehousing/StockIn/components/detail.vue
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 自定义导航栏 -->
|
||||||
|
<navigation :title="pathParams.billNo">
|
||||||
|
<template #right>
|
||||||
|
<view class="right-btn flex align-center justify-center ">
|
||||||
|
<uv-image @click="onPrinter" src="../../../../static/printer.png" width="20px" height="20px"
|
||||||
|
style="margin-top:10rpx" />
|
||||||
|
<uv-image @click="onEdit" src="../../../../static/edit.png" class="ml-24" width="20px" height="20px"
|
||||||
|
style="margin-top:10rpx" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</Navigation>
|
||||||
|
<!-- 详情信息 -->
|
||||||
|
<detail-info type="stockIn" :detailInfo="detailInfo" />
|
||||||
|
|
||||||
|
<view v-if="detailInfo?.billType == '0'"
|
||||||
|
:class="getBillType(detailInfo?.billType, detailInfo?.status) != '物料部分入库' ? 'bottom' : 'bottom1'">
|
||||||
|
<uv-button type="error" v-if="getBillType(detailInfo?.billType, detailInfo?.status) != '物料部分入库'" text="作废"
|
||||||
|
@click="toObsolete"></uv-button>
|
||||||
|
<uv-button type="primary" text="入库单入库" @click="toPutAway"></uv-button>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
|
import { objectToQuery, getBillType } from '../../../until';
|
||||||
|
import { stockInDetail, inboundBillVoid } from '../../../../api/stockIn';
|
||||||
|
import DetailInfo from '../../../components/DetailInfo.vue';
|
||||||
|
import Navigation from '../../../components/Navigation.vue';
|
||||||
|
|
||||||
|
// 数据:路径参数
|
||||||
|
const pathParams = ref('')
|
||||||
|
// 数据:详情
|
||||||
|
const detailInfo = ref('')
|
||||||
|
// 数据:类型 stockIn:入库 stockIn-putAway:入库单入库 stockOut:出库
|
||||||
|
const type = computed(() => pathParams.value.type)
|
||||||
|
// 方法:获取详情 - 将isDelete写入
|
||||||
|
const getDetailInfo = () => {
|
||||||
|
stockInDetail({ billNo: pathParams.value.billNo }).then((res) => {
|
||||||
|
detailInfo.value = res.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打印
|
||||||
|
const onPrinter = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
const toObsolete = () => {
|
||||||
|
const params = {
|
||||||
|
billNo: pathParams.value?.billNo,
|
||||||
|
billType: '5'
|
||||||
|
}
|
||||||
|
inboundBillVoid(params).then((res) => {
|
||||||
|
// /pages/warehousing/stockIn/my
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/warehousing/stockIn/my`
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
const setDetailInfoToStorage = (type) => {
|
||||||
|
uni.setStorageSync('app_warehousing', [{
|
||||||
|
deptName: detailInfo.value?.warehouseName,
|
||||||
|
deptCode: detailInfo.value?.warehouseCode,
|
||||||
|
}])
|
||||||
|
uni.setStorageSync('app_storageArea', [{
|
||||||
|
deptName: detailInfo.value?.areaName,
|
||||||
|
deptCode: detailInfo.value?.areaCode,
|
||||||
|
}])
|
||||||
|
if (type) {
|
||||||
|
const material = _.filter(detailInfo.value?.itemList, (i) => i?.uniqueCode && i.status == '0')
|
||||||
|
const materialSelectList = _.filter(detailInfo.value?.itemList, (i) => !i?.uniqueCode && i.status == '0')
|
||||||
|
uni.setStorageSync('app_material', material)
|
||||||
|
uni.setStorageSync('app_material_select_list', materialSelectList)
|
||||||
|
} else {
|
||||||
|
uni.setStorageSync('app_material', detailInfo.value?.itemList)
|
||||||
|
}
|
||||||
|
uni.setStorageSync('app_billRemark', detailInfo.value?.billRemark,)
|
||||||
|
|
||||||
|
}
|
||||||
|
// 按钮:入库单入库
|
||||||
|
const toPutAway = () => {
|
||||||
|
setDetailInfoToStorage('1')
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/warehousing/stockIn/components/inbound?billNo=${pathParams.value.billNo}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 编辑
|
||||||
|
const onEdit = () => {
|
||||||
|
setDetailInfoToStorage()
|
||||||
|
const query = objectToQuery(pathParams.value)
|
||||||
|
let url = `/pages/warehousing/stockIn/create${query}`
|
||||||
|
uni.navigateTo({
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 接收路径参数:billNo
|
||||||
|
onLoad((options) => {
|
||||||
|
if (!options.billNo) {
|
||||||
|
uni.showToast({ title: '参数错误,无唯一码ID', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pathParams.value = options
|
||||||
|
getDetailInfo()
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
/* 底部按钮 */
|
||||||
|
|
||||||
|
|
||||||
|
// 底部按钮
|
||||||
|
.bottom {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
height: 60rpx;
|
||||||
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.uv-button-wrapper {
|
||||||
|
width: 50%;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom1 {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
height: 60rpx;
|
||||||
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
// justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.uv-button-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
158
pages/warehousing/StockIn/components/inbound.vue
Normal file
158
pages/warehousing/StockIn/components/inbound.vue
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
<!--点击入库单入库后的入库页面 -->
|
||||||
|
<template>
|
||||||
|
<view class="page">
|
||||||
|
<!-- 仓库信息 - 仓库、存储区 -->
|
||||||
|
<warehousing-info ref="warehousingInfoRef" :warehouseInfo="warehouseInfo" :pathParams="pathParams" />
|
||||||
|
<!-- 物料列表 - 添加物料 -->
|
||||||
|
<material-list ref="materialRef" :formData="formData" isEdit="5" backStr="stockIn" :pathParams="pathParams"
|
||||||
|
:extendData="{ selectMaterialList }" />
|
||||||
|
<!-- 底部操作栏 -->
|
||||||
|
<view class="bottom">
|
||||||
|
<uv-button type="primary" @click="submitForm">入库</uv-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||||
|
import { inboundFinish, stockInDetail,inboundBillVoid } from '@/api/stockIn';
|
||||||
|
import MaterialList from '../../../components/MaterialList.vue';
|
||||||
|
import WarehousingInfo from '../../../components/WarehousingInfo.vue';
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
|
||||||
|
// 数据:路径参数
|
||||||
|
const pathParams = ref('')
|
||||||
|
// 标志:是否为编辑
|
||||||
|
const isEdit = ref('')
|
||||||
|
// 标志:区分页面 进入页面的状态 null新建 stockIn:入库编辑 stockIn-putAway:入库单入库编辑
|
||||||
|
const flag = ref('')
|
||||||
|
|
||||||
|
// ref:物料绑定
|
||||||
|
const materialRef = ref([])
|
||||||
|
// ref:仓库信息绑定
|
||||||
|
const warehousingInfoRef = ref([])
|
||||||
|
|
||||||
|
const selectMaterialList = ref([])
|
||||||
|
const detailInfo = ref('')
|
||||||
|
|
||||||
|
// 数据:物料列表
|
||||||
|
const formData = ref([{ remark: '', material: [] }])
|
||||||
|
// 数据:仓库信息
|
||||||
|
const warehouseInfo = ref({ warehousing: {}, storageArea: {}, remark: '' })
|
||||||
|
|
||||||
|
// 数据:获取缓存信息
|
||||||
|
const getMaterialList = () => {
|
||||||
|
// 获取仓库信息
|
||||||
|
const warehouse = uni.getStorageSync('app_warehousing');
|
||||||
|
warehouseInfo.value.warehousing = warehouse
|
||||||
|
|
||||||
|
// 获取存储区信息
|
||||||
|
const storageArea = uni.getStorageSync('app_storageArea');
|
||||||
|
warehouseInfo.value.storageArea = storageArea
|
||||||
|
// 获取物料信息 - 有uniqueCode
|
||||||
|
const material = uni.getStorageSync('app_material');
|
||||||
|
formData.value.material = material
|
||||||
|
// 获取物料信息 - 无uniqueCode
|
||||||
|
const selectMaterial = uni.getStorageSync('app_material_select_list');
|
||||||
|
selectMaterialList.value = selectMaterial
|
||||||
|
// 获取入库单备注
|
||||||
|
const billRemark = uni.getStorageSync('app_billRemark');
|
||||||
|
warehouseInfo.value.remark = billRemark
|
||||||
|
console.log('获取缓存', material, selectMaterial);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 方法:获取详情 - 更新物料得值 获取唯一码后回来
|
||||||
|
const getDetailInfo = () => {
|
||||||
|
stockInDetail({ billNo: pathParams.value.billNo }).then((res) => {
|
||||||
|
setDetailInfoToStorage(res.data?.itemList)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 方法:存入缓存 - 更新物料得值 获取唯一码后回来
|
||||||
|
const setDetailInfoToStorage = (val) => {
|
||||||
|
// 过滤出有uniqueCode得值
|
||||||
|
const material = _.filter(val, (i) => i?.uniqueCode && i.status == '0')
|
||||||
|
const materialSelectList = _.filter(val, (i) => !i?.uniqueCode && i.status == '0')
|
||||||
|
uni.setStorageSync('app_material', material)
|
||||||
|
uni.setStorageSync('app_material_select_list', materialSelectList)
|
||||||
|
getMaterialList()
|
||||||
|
}
|
||||||
|
// 入库:提交表单
|
||||||
|
const submitForm = () => {
|
||||||
|
const info = warehousingInfoRef.value.getWarehousingInfo()
|
||||||
|
const materialInfo = materialRef.value.getMaterialList()
|
||||||
|
// 过滤出已删除的物料
|
||||||
|
const _materialInfo = _.filter(materialInfo, { isDelete: '0' })
|
||||||
|
let params = {
|
||||||
|
billType: '1',//0入库申请 1入库成功 2出库申请 3出库成功 4入库单已作废 5出库单已作废
|
||||||
|
billNo: pathParams.value.billNo,
|
||||||
|
warehouseCode: info.warehousing?.[0].deptCode || info.warehousing?.[0].deptId,
|
||||||
|
warehouseName: info.warehousing?.[0].deptName,
|
||||||
|
areaCode: info.storageArea?.[0].deptCode || info.storageArea?.[0].deptId,
|
||||||
|
areaName: info.storageArea?.[0].deptName,
|
||||||
|
remark: info.remark,
|
||||||
|
billRemark: info.remark,
|
||||||
|
itemList: _.map(_materialInfo, (i) => ({ ...i.material }))
|
||||||
|
}
|
||||||
|
|
||||||
|
inboundFinish(params).then((res) => {
|
||||||
|
// stockIn
|
||||||
|
// /pages/warehousing/stockIn/components/detail
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/warehousing/stockIn/components/detail?billNo=${pathParams.value.billNo}&type=stockIn`
|
||||||
|
});
|
||||||
|
console.log(res, '入库单入库');
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
// 数据:路径参数
|
||||||
|
onLoad((options) => {
|
||||||
|
console.log(options, 'options', _.includes(options?.type, 'stockIn'));
|
||||||
|
if (!options.billNo) {
|
||||||
|
uni.showToast({ title: '参数错误,无唯一码ID', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pathParams.value = options
|
||||||
|
getDetailInfo()
|
||||||
|
flag.value = options.type
|
||||||
|
isEdit.value = _.includes(options?.type, 'stockIn')
|
||||||
|
})
|
||||||
|
// 修改标题:若有billNo传入 修改标题
|
||||||
|
onShow(() => {
|
||||||
|
if (pathParams.value.billNo) {
|
||||||
|
uni.setNavigationBarTitle({ title: pathParams.value.billNo })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
onMounted(() => {
|
||||||
|
getMaterialList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page {
|
||||||
|
background: #f5f5f5;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部按钮 */
|
||||||
|
::v-deep .bottom {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
height: 60rpx;
|
||||||
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.uv-button-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
206
pages/warehousing/StockIn/create.vue
Normal file
206
pages/warehousing/StockIn/create.vue
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
<template>
|
||||||
|
<view class="page">
|
||||||
|
<!-- 仓库信息 - 仓库、存储区 -->
|
||||||
|
<warehousing-info ref="warehousingInfoRef" :warehouseInfo="warehouseInfo" :pathParams="pathParams" />
|
||||||
|
<!-- 物料列表 - 添加物料 -->
|
||||||
|
<material-list ref="materialRef" :formData="formData" isEdit="1" backStr="stockIn" :pathParams="pathParams" />
|
||||||
|
<!-- 底部操作栏 -->
|
||||||
|
<view class="bottom">
|
||||||
|
<uv-button @click="scanCode">扫码添加</uv-button>
|
||||||
|
<uv-button type="primary" @click="submitForm">提交</uv-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { objectToQuery } from '../../until';
|
||||||
|
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||||
|
import { addStockIn, stockInUpdate } from '@/api/stockIn';
|
||||||
|
import { getMaterialUnique } from '@/api/uniqueCode';
|
||||||
|
import MaterialList from '../../components/MaterialList.vue';
|
||||||
|
import WarehousingInfo from '../../components/WarehousingInfo.vue';
|
||||||
|
|
||||||
|
|
||||||
|
// 数据:路径参数
|
||||||
|
const pathParams = ref('')
|
||||||
|
// 标志:是否为编辑
|
||||||
|
const isEdit = ref('')
|
||||||
|
// 标志:区分页面 进入页面的状态 null新建 stockIn:入库编辑 stockIn-putAway:入库单入库编辑
|
||||||
|
const flag = ref('')
|
||||||
|
|
||||||
|
// ref:物料绑定
|
||||||
|
const materialRef = ref([])
|
||||||
|
// ref:仓库信息绑定
|
||||||
|
const warehousingInfoRef = ref([])
|
||||||
|
|
||||||
|
// 数据:物料列表
|
||||||
|
const formData = ref([{ remark: '', material: [] }])
|
||||||
|
// 数据:仓库信息
|
||||||
|
const warehouseInfo = ref({ warehousing: {}, storageArea: {}, remark: '' })
|
||||||
|
|
||||||
|
// 数据:获取缓存信息
|
||||||
|
const getMaterialList = () => {
|
||||||
|
|
||||||
|
// 获取仓库信息
|
||||||
|
const warehouse = uni.getStorageSync('app_warehousing');
|
||||||
|
warehouseInfo.value.warehousing = warehouse
|
||||||
|
|
||||||
|
// 获取存储区信息
|
||||||
|
const storageArea = uni.getStorageSync('app_storageArea');
|
||||||
|
warehouseInfo.value.storageArea = storageArea
|
||||||
|
|
||||||
|
// 获取物料信息
|
||||||
|
const material = uni.getStorageSync('app_material');
|
||||||
|
formData.value.material = material
|
||||||
|
|
||||||
|
// 获取入库单备注
|
||||||
|
const billRemark = uni.getStorageSync('app_billRemark');
|
||||||
|
warehouseInfo.value.remark = billRemark
|
||||||
|
}
|
||||||
|
getMaterialList();
|
||||||
|
const scanResult = ref('')
|
||||||
|
// 扫码添加
|
||||||
|
const scanCode = () => {
|
||||||
|
// 先校验是否支持扫码
|
||||||
|
uni.scanCode({
|
||||||
|
scanType: ['qrCode', 'barCode'], // 支持二维码 + 条形码
|
||||||
|
success: (res) => {
|
||||||
|
scanResult.value = res.result;
|
||||||
|
if (res.result) {
|
||||||
|
getMaterialUnique({ code: res.result }).then((response) => {
|
||||||
|
console.log('物料内容:', response);
|
||||||
|
if (`${response.code}` === '200') {
|
||||||
|
const material = uni.getStorageSync('app_material');
|
||||||
|
// 处理物料信息 合并
|
||||||
|
const materialInfo = _.filter(material, { isDelete: '0' });
|
||||||
|
console.log('materialInfo', materialInfo);
|
||||||
|
const materialId = response.data?.[0]?.materialId;
|
||||||
|
console.log('materialId', materialId);
|
||||||
|
const idx = _.findIndex(materialInfo, (i) => i.materialId ? i.materialId == materialId : i.id == materialId);
|
||||||
|
console.log('已选中是否有重复数据', idx);
|
||||||
|
|
||||||
|
if (idx != -1) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '该物料已添加,请勿重复添加!',
|
||||||
|
mask: true,
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
let _material = [...materialInfo, { ...response.data[0],uniqueCode:res.result }]
|
||||||
|
console.log('新的物料数组', _material);
|
||||||
|
formData.value.material = _material
|
||||||
|
uni.setStorageSync('app_material', formData.value.material)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(response.code, 'response.code');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: () => {
|
||||||
|
uni.showToast({ title: '扫码失败', icon: 'none' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const submitForm = () => {
|
||||||
|
const info = warehousingInfoRef.value.getWarehousingInfo()
|
||||||
|
const materialInfo = materialRef.value.getMaterialList()
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
warehouseCode: info.warehousing?.[0].deptCode || info.warehousing?.[0].deptId,
|
||||||
|
warehouseName: info.warehousing?.[0].deptName,
|
||||||
|
areaCode: info.storageArea?.[0].deptCode || info.storageArea?.[0].deptId,
|
||||||
|
areaName: info.storageArea?.[0].deptName,
|
||||||
|
remark: info.remark,
|
||||||
|
billRemark: info.remark,
|
||||||
|
itemList: _.map(materialInfo, (i) => ({ ...i.material }))
|
||||||
|
}
|
||||||
|
console.log(params, isEdit, !isEdit, info, materialInfo, '入参params');
|
||||||
|
// 新建
|
||||||
|
if (!isEdit.value) {
|
||||||
|
addStockIn(params).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '入库单创建成功',
|
||||||
|
mask: true,
|
||||||
|
icon: 'success',
|
||||||
|
})
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/warehousing/stockIn/my`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
} else if (isEdit.value) {
|
||||||
|
// 编辑
|
||||||
|
params.billNo = pathParams.value?.billNo
|
||||||
|
params.billId = pathParams.value?.billId
|
||||||
|
const query = objectToQuery(pathParams.value)
|
||||||
|
stockInUpdate(params).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '入库单编辑成功',
|
||||||
|
mask: true,
|
||||||
|
icon: 'success',
|
||||||
|
})
|
||||||
|
let url = `/pages/warehousing/stockIn/components/detail${query}`
|
||||||
|
uni.navigateTo({
|
||||||
|
url: url,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// 数据:路径参数
|
||||||
|
onLoad((options) => {
|
||||||
|
console.log(options, 'options', _.includes(options?.type, 'stockIn'));
|
||||||
|
|
||||||
|
pathParams.value = options
|
||||||
|
flag.value = options.type
|
||||||
|
isEdit.value = _.includes(options?.type, 'stockIn')
|
||||||
|
})
|
||||||
|
// 修改标题:若有billNo传入 修改标题
|
||||||
|
onShow(() => {
|
||||||
|
if (pathParams.value.billNo) {
|
||||||
|
uni.setNavigationBarTitle({ title: pathParams.value.billNo })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page {
|
||||||
|
background: #f5f5f5;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部按钮 */
|
||||||
|
::v-deep .bottom {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
height: 60rpx;
|
||||||
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.uv-button-wrapper {
|
||||||
|
width: 50%;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uv-button--info {
|
||||||
|
background-color: #07c160;
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
9
pages/warehousing/StockIn/my.vue
Normal file
9
pages/warehousing/StockIn/my.vue
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<search-list type="stockIn" :onDetail="onDetail" />
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import SearchList from '../../components/SearchList.vue';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
10
pages/warehousing/StockIn/putaway.vue
Normal file
10
pages/warehousing/StockIn/putaway.vue
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<!-- putAway:入库单入库 -->
|
||||||
|
<template>
|
||||||
|
<search-list type="stockIn-putAway" :onDetail="onDetail" :query="{ billType: '0' }" />
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import SearchList from '../../components/SearchList.vue';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<!-- 底部导航栏:仓库 -->
|
||||||
<template>
|
<template>
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<uni-card v-for="(item, index) in menuList" :key="item.id" :title="item.title" :isFull="true"
|
<uni-card v-for="(item, index) in menuList" :key="item.id" :title="item.title" :isFull="true"
|
||||||
@@ -12,7 +13,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onShow } from '@dcloudio/uni-app';
|
import { onShow } from '@dcloudio/uni-app';
|
||||||
|
import {removeStorage} from '../until';
|
||||||
const menuList = [
|
const menuList = [
|
||||||
{
|
{
|
||||||
id: 'inventory',
|
id: 'inventory',
|
||||||
@@ -125,7 +126,11 @@ const menuList = [
|
|||||||
icon: '../../static/stockInOrOut/stockInCreateOrder.png',
|
icon: '../../static/stockInOrOut/stockInCreateOrder.png',
|
||||||
title: '入库单开单',
|
title: '入库单开单',
|
||||||
click: () => {
|
click: () => {
|
||||||
|
removeStorage()
|
||||||
console.log('入库单开单')
|
console.log('入库单开单')
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/warehousing/stockIn/create'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -134,6 +139,10 @@ const menuList = [
|
|||||||
title: '我的入库单',
|
title: '我的入库单',
|
||||||
click: () => {
|
click: () => {
|
||||||
console.log('我的入库单')
|
console.log('我的入库单')
|
||||||
|
removeStorage()
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/warehousing/stockIn/my'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -142,6 +151,9 @@ const menuList = [
|
|||||||
title: '入库单入库',
|
title: '入库单入库',
|
||||||
click: () => {
|
click: () => {
|
||||||
console.log('入库单入库')
|
console.log('入库单入库')
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/warehousing/stockIn/putaway'
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -188,9 +200,9 @@ const menuList = [
|
|||||||
title: '唯一码发放',
|
title: '唯一码发放',
|
||||||
click: () => {
|
click: () => {
|
||||||
console.log('唯一码发放')
|
console.log('唯一码发放')
|
||||||
uni.setStorageSync('app_material', []);
|
uni.removeStorage('app_material')
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: '/pages/uniqueCode/issueUniqueCode/index'
|
url: '/pages/warehousing/uniqueCode/issueUniqueCode/index'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -201,7 +213,7 @@ const menuList = [
|
|||||||
click: () => {
|
click: () => {
|
||||||
console.log('唯一码')
|
console.log('唯一码')
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: '/pages/uniqueCode/myUniqueCode/index'
|
url: '/pages/warehousing/uniqueCode/myUniqueCode/index'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -216,28 +228,28 @@ const menuList = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
id: 'transportCheckIn',
|
// id: 'transportCheckIn',
|
||||||
title: '运输打卡',
|
// title: '运输打卡',
|
||||||
menuItem: [
|
// menuItem: [
|
||||||
{
|
// {
|
||||||
id: "transportCheckIn_transportCheckIn",
|
// id: "transportCheckIn_transportCheckIn",
|
||||||
icon: '../../static/transportCheckIn/transportCheckIn.png',
|
// icon: '../../static/transportCheckIn/transportCheckIn.png',
|
||||||
title: '运输打卡',
|
// title: '运输打卡',
|
||||||
click: () => {
|
// click: () => {
|
||||||
console.log('运输打卡')
|
// console.log('运输打卡')
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
id: "transportCheckIn_myTransportCheckIn",
|
// id: "transportCheckIn_myTransportCheckIn",
|
||||||
icon: '../../static/transportCheckIn/myTransportCheckIn.png',
|
// icon: '../../static/transportCheckIn/myTransportCheckIn.png',
|
||||||
title: '我的运输打卡',
|
// title: '我的运输打卡',
|
||||||
click: () => {
|
// click: () => {
|
||||||
console.log('我的运输打卡')
|
// console.log('我的运输打卡')
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
]
|
// ]
|
||||||
},
|
// },
|
||||||
]
|
]
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
uni.removeStorage({
|
uni.removeStorage({
|
||||||
@@ -249,7 +261,6 @@ onShow(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
/* 覆盖 uni-card 根容器样式 */
|
|
||||||
::v-deep .custom-card.uni-card {
|
::v-deep .custom-card.uni-card {
|
||||||
margin-bottom: 6rpx !important;
|
margin-bottom: 6rpx !important;
|
||||||
border-color: #F8F8FF !important;
|
border-color: #F8F8FF !important;
|
||||||
|
|||||||
18
pages/warehousing/toChooseList.vue
Normal file
18
pages/warehousing/toChooseList.vue
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!-- 仓库信息选择 -->
|
||||||
|
<template>
|
||||||
|
<choose-list :isWarehousing="isWarehousing" :backStr="pathParams.backStr" :pathParams="pathParams" />
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
|
import ChooseList from '../components/ChooseList.vue'
|
||||||
|
|
||||||
|
// 路径参数
|
||||||
|
const pathParams = ref('')
|
||||||
|
const isWarehousing = computed(() => pathParams.value.flag == 'warehousing')
|
||||||
|
// 接收路径参数
|
||||||
|
onLoad((options) => {
|
||||||
|
pathParams.value = options
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
205
pages/warehousing/uniqueCode/issueUniqueCode/index.vue
Normal file
205
pages/warehousing/uniqueCode/issueUniqueCode/index.vue
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
<!-- 唯一码发放页面 -->
|
||||||
|
<template>
|
||||||
|
<view class="content">
|
||||||
|
<view class="remarkLine">
|
||||||
|
<span>备注:</span>
|
||||||
|
<uni-easyinput type="text" v-model="formData.remark" :inputBorder="false" placeholder="请输入备注" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 物料列表 - 添加物料 -->
|
||||||
|
<material-list ref="materialRef" :formData="formData" :remark="formData.remark" isEdit="1" :backStr="backStr"
|
||||||
|
:pathParams="pathParams" />
|
||||||
|
<button class="bottom-btn" type="primary" @click="handleSubmit">提交</button>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
|
import { addUniqueCode, editUniqueCode } from '@/api/uniqueCode';
|
||||||
|
import MaterialList from '../../../components/MaterialList.vue';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
// 数据:路径参数
|
||||||
|
const pathParams = ref('')
|
||||||
|
// 数据:物料、备注
|
||||||
|
const formData = ref({ remark: '', material: [] })
|
||||||
|
// ref:绑定物料列表
|
||||||
|
const materialRef = ref([])
|
||||||
|
const backStr = computed(() => pathParams.value.back == 'inbound' ? `issueUniqueCode_inbound` : 'issueUniqueCode')
|
||||||
|
// 接收路径参数 - 修改标题- 携带code、id、materialId
|
||||||
|
onLoad((options) => {
|
||||||
|
pathParams.value = options
|
||||||
|
|
||||||
|
})
|
||||||
|
onShow(() => {
|
||||||
|
if (pathParams.value.title) {
|
||||||
|
uni.setNavigationBarTitle({ title: pathParams.value.title })
|
||||||
|
}
|
||||||
|
if (pathParams.value.back == 'inbound') {
|
||||||
|
uni.setNavigationBarTitle({ title: '快速生成唯一码' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 快速生成唯一码时 已选择的物料列表初始为空 点击添加物料 去选择
|
||||||
|
if (pathParams.value.back != 'inbound') {
|
||||||
|
getMaterialList();
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
// 创建/编辑 唯一码
|
||||||
|
const handleSubmit = () => {
|
||||||
|
// 物料最新编辑数据
|
||||||
|
const material = materialRef.value.getMaterialList()?.[0]
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
remark: formData.value.remark,
|
||||||
|
material: { ...material.material, unitId: '23' }
|
||||||
|
}
|
||||||
|
if (pathParams.value.back == `issueUniqueCode_inbound`) {
|
||||||
|
params.billNo = pathParams.value.billNo
|
||||||
|
}
|
||||||
|
if (pathParams.value.id) {
|
||||||
|
params.id = pathParams.value.id; //唯一码id
|
||||||
|
params.material.id = formData.value.material?.[0]?.uniqueCodeMaterialId; //唯一码物料id
|
||||||
|
params.material.materialId = formData.value.material?.[0]?.materialId; //物料id
|
||||||
|
editUniqueCode(params).then((response) => {
|
||||||
|
if (response.code == 200) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '唯一码编辑成功',
|
||||||
|
mask: true,
|
||||||
|
icon: 'success',
|
||||||
|
})
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/warehousing/uniqueCode/myUniqueCode/detail?id=${pathParams.value.id}&title=${pathParams.value.title}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
addUniqueCode(params).then((response) => {
|
||||||
|
if (response.code == 200) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '唯一码创建成功',
|
||||||
|
mask: true,
|
||||||
|
icon: 'success',
|
||||||
|
})
|
||||||
|
if (_.includes(pathParams.value?.back, 'inbound')) {
|
||||||
|
// /pages/warehousing/uniqueCode/myUniqueCode/detail?id=38&code=600038
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/warehousing/stockIn/components/inbound?billNo=${pathParams.value.billNo}`,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.switchTab({
|
||||||
|
url: "/pages/warehousing/index"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// /pages/warehousing/stockIn/components/inbound?billNo=WR1775032495153
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取缓存内的物料列表
|
||||||
|
const getMaterialList = () => {
|
||||||
|
const value = uni.getStorageSync('app_material');
|
||||||
|
if (value) {
|
||||||
|
formData.value.material = value
|
||||||
|
if (value?.[0]?.uniqueCodeRemark) {
|
||||||
|
formData.value.remark = value?.[0]?.uniqueCodeRemark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.remarkLine {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #fff;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 8rpx 24rpx;
|
||||||
|
margin-bottom: 8rpx;
|
||||||
|
min-height: 40rpx;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .uv-button {
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .form {
|
||||||
|
.title {
|
||||||
|
color: #424242;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
.uni-tag {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: calc(25px - 6px);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-form {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-forms-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.uni-easyinput__content,
|
||||||
|
.uni-easyinput__content-input {
|
||||||
|
height: 25px;
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark {
|
||||||
|
.uni-forms-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-top: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.uni-forms-item__label {
|
||||||
|
color: #212121;
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-easyinput__content-input {
|
||||||
|
height: 40rpx;
|
||||||
|
|
||||||
|
.uni-input-wrapper {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-input-placeholder {
|
||||||
|
text-align: right;
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
<!-- 物料选择 -->
|
||||||
|
<template>
|
||||||
|
<view class="content">
|
||||||
|
<view class="topSearch" v-if="!backUrl.includes('inbound')">
|
||||||
|
<uni-easyinput type="text" v-model="queryParams.keyword" prefixIcon="search" :inputBorder="false"
|
||||||
|
@iconClick="getMaterialList" placeholder="请输入搜索内容" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 物料列表 -->
|
||||||
|
<z-paging ref="pagingRef" class="containerBox" v-model="materialList" @query="getMaterialList"
|
||||||
|
v-if="!backUrl.includes('inbound')">
|
||||||
|
<uni-list>
|
||||||
|
<uni-list-item v-for="item in materialList" :key="item.id" clickable class="material-card"
|
||||||
|
@click="onMaterial(item)">
|
||||||
|
<template v-slot:body>
|
||||||
|
<p style="display: flex; flex-direction: column; width: 100%;">
|
||||||
|
<p class="title">{{ item.materialName }} ({{ item.materialCode }})</p>
|
||||||
|
<p class="subTitle">
|
||||||
|
<!-- 简称/型号/规格/类型 -->
|
||||||
|
<span v-if="item.materialShortName">{{ item.materialShortName }} / </span>
|
||||||
|
<span v-if="item.model">{{ item.model }} / </span>
|
||||||
|
<span v-if="item.specification">{{ item.specification }} / </span>
|
||||||
|
<span v-if="item.typeName">{{ item.typeName }} </span>
|
||||||
|
</p>
|
||||||
|
<p class="tag">
|
||||||
|
<uni-tag :text="getTypeParentNames(item.typeParentNames)" type="error" />
|
||||||
|
<p>单位:{{ item.unitName }}</p>
|
||||||
|
</p>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</uni-list-item>
|
||||||
|
</uni-list>
|
||||||
|
</z-paging>
|
||||||
|
|
||||||
|
<view v-if="backUrl.includes('inbound')">
|
||||||
|
<uni-list>
|
||||||
|
<uni-list-item v-for="item in materialList" :key="item.id" clickable class="material-card"
|
||||||
|
@click="onMaterial(item)">
|
||||||
|
<template v-slot:body>
|
||||||
|
<p style="display: flex; flex-direction: column; width: 100%;">
|
||||||
|
<p class="title">{{ item.materialName }} ({{ item.materialCode }})</p>
|
||||||
|
<p class="subTitle">
|
||||||
|
<!-- 简称/型号/规格/类型 -->
|
||||||
|
<span v-if="item.materialShortName">{{ item.materialShortName }} / </span>
|
||||||
|
<span v-if="item.model">{{ item.model }} / </span>
|
||||||
|
<span v-if="item.specification">{{ item.specification }} / </span>
|
||||||
|
<span v-if="item.typeName">{{ item.typeName }} </span>
|
||||||
|
</p>
|
||||||
|
<p class="tag">
|
||||||
|
<uni-tag :text="getTypeParentNames(item.typeParentNames)" type="error" />
|
||||||
|
<p>单位:{{ item.unitName }}</p>
|
||||||
|
</p>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</uni-list-item>
|
||||||
|
</uni-list>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { getTypeParentNames, } from '../until';
|
||||||
|
import { objectToQuery } from '../../../until';
|
||||||
|
import { getMaterial } from '@/api/uniqueCode'
|
||||||
|
import { onShow, onLoad } from "@dcloudio/uni-app";
|
||||||
|
|
||||||
|
// ref:下拉加载
|
||||||
|
const pagingRef = ref(null)
|
||||||
|
// 数据:查询参数
|
||||||
|
const queryParams = ref({
|
||||||
|
keyword: ''
|
||||||
|
})
|
||||||
|
// 数据:物料
|
||||||
|
const materialList = ref([])
|
||||||
|
// 数据:路径参数
|
||||||
|
const pathParams = ref('')
|
||||||
|
|
||||||
|
// 数据:返回路径标识 stockIn 入库单开单 stockInDetail入库单编辑 issueUniqueCode唯一码 issueUniqueCode_inbound入库生成唯一码
|
||||||
|
const backUrl = computed(() => pathParams?.value?.back)
|
||||||
|
// 方法:获取列表
|
||||||
|
const getMaterialList = () => {
|
||||||
|
getMaterial(queryParams.value).then(res => {
|
||||||
|
res.rows.forEach(e => {
|
||||||
|
e.showMore = false;
|
||||||
|
});
|
||||||
|
pagingRef.value.complete(res.rows)
|
||||||
|
}).catch(res => {
|
||||||
|
pagingRef.value.complete(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 方法:获取列表 - 入库生成唯一码
|
||||||
|
const getMaterialListInbound = () => {
|
||||||
|
const list = uni.getStorageSync('app_material_select_list')
|
||||||
|
console.log('list',list);
|
||||||
|
materialList.value=list
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
pagingRef.value?.reload?.()
|
||||||
|
})
|
||||||
|
onLoad((options) => {
|
||||||
|
pathParams.value = options
|
||||||
|
getMaterialListInbound()
|
||||||
|
})
|
||||||
|
// 方法:获取缓存物料信息
|
||||||
|
const getStorageMaterial = (val) => {
|
||||||
|
// 唯一码编辑进入 数量默认1\唯一码物料表id\物料id
|
||||||
|
if (pathParams.value.id) {
|
||||||
|
const value = uni.getStorageSync('app_material');
|
||||||
|
if (value && value?.length > 0) {
|
||||||
|
return [{ ...val, quantity: 1, uniqueCodeMaterialId: value?.[0]?.id, uniqueCodeRemark: value?.[0]?.uniqueCodeRemark, materialId: val.id, isDelete: '0' }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [{ ...val, quantity: 1 }]
|
||||||
|
}
|
||||||
|
// 方法:返回路径
|
||||||
|
const toBack = (back) => {
|
||||||
|
const path = objectToQuery({ ...pathParams.value })
|
||||||
|
let url = ''
|
||||||
|
switch (back) {
|
||||||
|
case 'stockIn':
|
||||||
|
// 入库单开单添加物料进入
|
||||||
|
url = `/pages/warehousing/stockIn/create`
|
||||||
|
break
|
||||||
|
case 'issueUniqueCode':
|
||||||
|
case 'issueUniqueCode_inbound':
|
||||||
|
// 唯一码发放/入库生成唯一码
|
||||||
|
url = `/pages/warehousing/uniqueCode/issueUniqueCode/index`
|
||||||
|
break
|
||||||
|
case 'stockInDetail':
|
||||||
|
//我的入库单/入库单入库
|
||||||
|
url = `/pages/warehousing/stockIn/components/detail`
|
||||||
|
break
|
||||||
|
}
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `${url}${path}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 方法:选择物料
|
||||||
|
const onMaterial = (val) => {
|
||||||
|
let materialChecked = uni.getStorageSync('app_material');
|
||||||
|
if (!Array.isArray(materialChecked)) {
|
||||||
|
materialChecked = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(materialChecked, 'materialChecked==>');
|
||||||
|
|
||||||
|
const item = _.find(materialChecked, (i) => i.materialId ? i.materialId === val.id : i.id === val.id)
|
||||||
|
console.log(item, 'item==>');
|
||||||
|
|
||||||
|
const idx = _.findIndex(materialChecked, (i) => i.materialId ? i.materialId === val.id : i.id === val.id)
|
||||||
|
console.log(idx, 'idx==>', idx != -1 && item?.isDelete == '0', backUrl.value);
|
||||||
|
|
||||||
|
if (idx != -1 && item?.isDelete == '0') { // isDelete为0表示未删除 1为已删除数据不在对比范围内
|
||||||
|
console.log(backUrl.value == 'stockIn', '11111111111111111111111111');
|
||||||
|
|
||||||
|
if (backUrl.value == 'stockIn') {
|
||||||
|
console.log(111111111111);
|
||||||
|
|
||||||
|
uni.showToast({
|
||||||
|
title: '该物料已添加,请勿重复添加!',
|
||||||
|
mask: true,
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//! 现在仅允许添加一条物料打印一个唯一码 但保留可添加多个
|
||||||
|
// uni.showToast({
|
||||||
|
// title: '该物料已添加,请勿重复添加!',
|
||||||
|
// mask: true,
|
||||||
|
// icon: 'none',
|
||||||
|
// })
|
||||||
|
toBack(backUrl.value)
|
||||||
|
} else {
|
||||||
|
console.log('执行到这里');
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
if (backUrl.value == 'stockIn') {
|
||||||
|
materialChecked = [...materialChecked, { ...val, quantity: 1, isDelete: '0' }];
|
||||||
|
} else {
|
||||||
|
materialChecked = getStorageMaterial(val)
|
||||||
|
}
|
||||||
|
uni.setStorageSync('app_material', materialChecked);
|
||||||
|
}
|
||||||
|
toBack(backUrl.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.topSearch {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 999;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.containerBox {
|
||||||
|
// padding: 0 12rpx;
|
||||||
|
padding-top: 60px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.zp-l-text-rpx {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
112
pages/warehousing/uniqueCode/myUniqueCode/QrCodeModal.vue
Normal file
112
pages/warehousing/uniqueCode/myUniqueCode/QrCodeModal.vue
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<template>
|
||||||
|
<view style="display: block;">
|
||||||
|
<view class="top">
|
||||||
|
<uv-image src="../../../../static//logo/logo.jpg" width="40px" height="40px" style="margin-top:10rpx" />
|
||||||
|
|
||||||
|
<!-- 唯一兼容 iPad 的写法:纯 2D Canvas -->
|
||||||
|
<canvas id="barcode" type="2d" class="barcode-canvas"></canvas>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="content mt-16">
|
||||||
|
<p>物料:
|
||||||
|
<span>{{ material?.materialName }}</span>
|
||||||
|
<span v-if="material?.quantity">x {{ material?.quantity }}</span>
|
||||||
|
</p>
|
||||||
|
<p>描述:
|
||||||
|
<span v-if="material?.description">{{ material?.description || '-' }}</span>
|
||||||
|
<span v-else>
|
||||||
|
<span v-if="material?.materialShortName">{{ material?.materialShortName }} / </span>
|
||||||
|
<span v-if="material?.model">{{ material?.model }} / </span>
|
||||||
|
<span v-if="material?.specification">{{ material?.specification }} / </span>
|
||||||
|
<span v-if="material?.typeName">{{ material?.typeName }} </span>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<view class="top">
|
||||||
|
<p>备注:
|
||||||
|
<span>{{ material?.uniqueCodeRemark || '' }}</span>
|
||||||
|
</p>
|
||||||
|
<uv-image :src="qrCode" width="80rpx" height="80rpx" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, computed, watch } from 'vue';
|
||||||
|
import JsBarcode from 'jsbarcode';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
detail: { type: Object, default: null }
|
||||||
|
});
|
||||||
|
|
||||||
|
const qrCode = computed(() => props.detail?.material?.[0]?.qrCode);
|
||||||
|
const material = computed(() => props.detail?.material?.[0]);
|
||||||
|
const barcodeValue = computed(() => props.detail?.material?.[0]?.code || '');
|
||||||
|
|
||||||
|
|
||||||
|
// iPad 兼容核心:不用 document,只用 uni 官方 API
|
||||||
|
const drawBarcode = () => {
|
||||||
|
if (!barcodeValue.value) return;
|
||||||
|
|
||||||
|
const query = uni.createSelectorQuery();
|
||||||
|
query.select('#barcode')
|
||||||
|
.fields({ node: true, size: true })
|
||||||
|
.exec((res) => {
|
||||||
|
const canvas = res[0]?.node;
|
||||||
|
if (!canvas) return;
|
||||||
|
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
// 渲染条形码
|
||||||
|
JsBarcode(canvas, barcodeValue.value, {
|
||||||
|
format: 'CODE128',
|
||||||
|
width: 2,
|
||||||
|
height: 40,
|
||||||
|
displayValue: false,
|
||||||
|
margin: 10,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 延迟执行,保证 iPad 能加载
|
||||||
|
onMounted(() => {
|
||||||
|
setTimeout(drawBarcode, 400);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 数据变化重新绘制
|
||||||
|
watch(
|
||||||
|
() => props.detail,
|
||||||
|
() => setTimeout(drawBarcode, 400),
|
||||||
|
{ deep: true }
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.top {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
|
||||||
|
// display: flex;
|
||||||
|
p {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 必须给宽度高度,iPad 才会显示 */
|
||||||
|
.barcode-canvas {
|
||||||
|
width: 40%;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
184
pages/warehousing/uniqueCode/myUniqueCode/detail.vue
Normal file
184
pages/warehousing/uniqueCode/myUniqueCode/detail.vue
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
<!-- 唯一码详情 -->
|
||||||
|
<template>
|
||||||
|
<!-- 自定义导航栏 -->
|
||||||
|
<navigation :title="pathParams.code ? pathParams.code : '唯一码发放'">
|
||||||
|
<template #right>
|
||||||
|
<view class="right-btn flex align-center justify-center ">
|
||||||
|
<uv-image @click="toEdit" src="../../../../static/edit.png" class="ml-24" width="20px" height="20px"
|
||||||
|
style="margin-top:10rpx" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</Navigation>
|
||||||
|
<uv-skeletons :loading="loading" :skeleton="skeleton">
|
||||||
|
<view class=" content">
|
||||||
|
<!-- 唯一码展示 -->
|
||||||
|
<uni-list>
|
||||||
|
<uni-list-item v-for="item in uniqueCodeList" :key="item.id" clickable class="material-card">
|
||||||
|
<template v-slot:body>
|
||||||
|
<p style="display: flex; flex-direction: column; width: 100%;">
|
||||||
|
<!-- 编码、状态行 -->
|
||||||
|
<view class="flex-center">
|
||||||
|
<p class="title">编号:{{ item.code }}</p>
|
||||||
|
<p class="status">{{ getStatusName(item.status) }}</p>
|
||||||
|
</view>
|
||||||
|
<!-- 内容行 -->
|
||||||
|
<view class="text">
|
||||||
|
<p>RFID:
|
||||||
|
<span v-if="item.rfidCode">{{ item.remark }}</span>
|
||||||
|
<span v-else style="color: #999;">未绑定RFID</span>
|
||||||
|
</p>
|
||||||
|
<p>生成时间:
|
||||||
|
<span>{{ item?.createTime }}</span>
|
||||||
|
</p>
|
||||||
|
<!-- 备注行-->
|
||||||
|
<view class="flex-center qrCode">
|
||||||
|
<p>备注:
|
||||||
|
<span v-if="item.remark">{{ item.remark }}</span>
|
||||||
|
<span v-else style="color: #999;">未填写</span>
|
||||||
|
</p>
|
||||||
|
<view @click="toViewQrCode">
|
||||||
|
<uv-image src="../../../../static/qrcode.png" width="40rpx" height="40rpx"
|
||||||
|
style="margin-top:10rpx" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
</uni-list-item>
|
||||||
|
</uni-list>
|
||||||
|
<!-- 物料列表 -只读 -->
|
||||||
|
<view>
|
||||||
|
<material-list ref="materialRef" :formData="materialList" isEdit="2" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<view class="bottom">
|
||||||
|
<uv-button type="primary" text="唯一码打印"></uv-button>
|
||||||
|
<uv-button type="success" text="溯源" @click="toTraceability"></uv-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uv-skeletons>
|
||||||
|
<uv-modal ref="modalRef" :title="none" class="qrCodeModal" width="480rpx" :showConfirmButton="false">
|
||||||
|
<qr-code-modal :detail="materialList" />
|
||||||
|
</uv-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
|
import { detailUniqueCode } from '@/api/uniqueCode'
|
||||||
|
import { getStatusName, getDetail } from '../until';
|
||||||
|
import QrCodeModal from './QrCodeModal.vue';
|
||||||
|
import MaterialList from '../../../components/MaterialList.vue'
|
||||||
|
import Navigation from '../../../components/Navigation.vue'
|
||||||
|
|
||||||
|
const modalRef = ref()
|
||||||
|
// 路径参数
|
||||||
|
const pathParams = ref('')
|
||||||
|
// 物料列表数组
|
||||||
|
const materialList = ref({
|
||||||
|
material: {},
|
||||||
|
remark: ''
|
||||||
|
})
|
||||||
|
// 唯一码数组
|
||||||
|
const uniqueCodeList = ref([])
|
||||||
|
// 详情数据
|
||||||
|
const detail = ref([])
|
||||||
|
// 骨架屏开关
|
||||||
|
const loading = ref(true)
|
||||||
|
// 骨架屏样式
|
||||||
|
const skeleton = [{
|
||||||
|
type: 'line',
|
||||||
|
num: 3,
|
||||||
|
gap: '20rpx',
|
||||||
|
style: ['width: 200rpx;marginBottom: 50rpx;marginTop:50rpx;padding:24rpx', 'height: 100rpx;', 'width: 500rpx;'],
|
||||||
|
}]
|
||||||
|
const toViewQrCode = () => {
|
||||||
|
modalRef.value.open()
|
||||||
|
|
||||||
|
}
|
||||||
|
// 详情:唯一码
|
||||||
|
const getDetailInfo = () => {
|
||||||
|
detailUniqueCode({ id: pathParams.value.id }).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
// ! 写成数组原因 为了适应可多个物料生成唯一码
|
||||||
|
// 将物料写入信息以及物料详细信息解构出来、以及qrCode、唯一码对应的物料code、qrCodeMark仅用于二维码页面的备注展示
|
||||||
|
materialList.value.material = [{
|
||||||
|
...res.data.material,
|
||||||
|
...getDetail(res.data.material.wornMaterial),
|
||||||
|
qrCode: res.data.qrCode,
|
||||||
|
code: res.data.code, //唯一码code
|
||||||
|
uniqueCodeMaterialId: res.data.material.id, //唯一码物料id
|
||||||
|
uniqueCodeRemark: res.data.remark, //唯一码备注
|
||||||
|
}]
|
||||||
|
// 唯一码备注
|
||||||
|
materialList.value.remark = res.data.remark
|
||||||
|
uniqueCodeList.value = [res.data]
|
||||||
|
|
||||||
|
console.log('详情数据:唯一码materialList', materialList);
|
||||||
|
// 更新缓存物料值
|
||||||
|
uni.setStorageSync('app_material', materialList.value.material);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
materialList.value = []
|
||||||
|
uniqueCodeList.value = []
|
||||||
|
uni.showToast({ title: '暂无数据', icon: 'none' })
|
||||||
|
}
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 溯源
|
||||||
|
const toTraceability = () => {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改:唯一码的物料信息 - 携带title和唯一码id
|
||||||
|
const toEdit = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/warehousing/uniqueCode/issueUniqueCode/index?title=${pathParams.value.code}&id=${pathParams.value.id}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
// 接收id 且修改标题
|
||||||
|
onLoad((options) => {
|
||||||
|
if (!options.id) {
|
||||||
|
loading.value = false
|
||||||
|
uni.showToast({ title: '参数错误,无唯一码ID', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pathParams.value = options
|
||||||
|
getDetailInfo()
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
uni.setNavigationBarTitle({ title: pathParams.value.code })
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
// 底部按钮
|
||||||
|
.bottom {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
height: 60rpx;
|
||||||
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.uv-button-wrapper {
|
||||||
|
width: 50%;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep.qrCodeModal {
|
||||||
|
.uv-modal__content {
|
||||||
|
display: block !important;
|
||||||
|
padding: 24rpx;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
<span v-else style="color: #999;">未填写</span>
|
<span v-else style="color: #999;">未填写</span>
|
||||||
</p>
|
</p>
|
||||||
<view @click.stop="getDetailInfo(item)">
|
<view @click.stop="getDetailInfo(item)">
|
||||||
<uv-image src="../../../static/qrcode.png" width="40rpx" height="40rpx"
|
<uv-image src="../../../../static/qrcode.png" width="40rpx" height="40rpx"
|
||||||
style="margin-top:10rpx" />
|
style="margin-top:10rpx" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -79,9 +79,13 @@ const isDialog = ref(false)
|
|||||||
// 唯一码列表
|
// 唯一码列表
|
||||||
const uniqueCodeList = ref([])
|
const uniqueCodeList = ref([])
|
||||||
// 物料列表数组
|
// 物料列表数组
|
||||||
const materialList = ref([])
|
const materialList = ref({
|
||||||
|
material: []
|
||||||
|
})
|
||||||
// 列表:唯一码
|
// 列表:唯一码
|
||||||
const getMaterialList = () => {
|
const getMaterialList = (pageNo, pageSize) => {
|
||||||
|
queryParams.value.pageNum = pageNo
|
||||||
|
console.log(pageNo, pageSize, queryParams.value)
|
||||||
getUniqueCodeList(queryParams.value).then(res => {
|
getUniqueCodeList(queryParams.value).then(res => {
|
||||||
res.rows.forEach(e => {
|
res.rows.forEach(e => {
|
||||||
e.showMore = false;
|
e.showMore = false;
|
||||||
@@ -99,7 +103,7 @@ onShow(() => {
|
|||||||
// 详情:唯一码
|
// 详情:唯一码
|
||||||
const toDetail = (val) => {
|
const toDetail = (val) => {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pages/uniqueCode/myUniqueCode/detail?id=${val.id}&code=${val.code}`,
|
url: `/pages/warehousing/uniqueCode/myUniqueCode/detail?id=${val.id}&code=${val.code}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +122,6 @@ const dialogClose = () => {
|
|||||||
const dialogConfirm = () => {
|
const dialogConfirm = () => {
|
||||||
console.log(delItem.value.id, 'delItem.value.id');
|
console.log(delItem.value.id, 'delItem.value.id');
|
||||||
delUniqueCode({ ids: [delItem.value.id] }).then(res => {
|
delUniqueCode({ ids: [delItem.value.id] }).then(res => {
|
||||||
console.log(res, '11');
|
|
||||||
dialogClose()
|
dialogClose()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -126,7 +129,7 @@ const dialogConfirm = () => {
|
|||||||
const getDetailInfo = (row) => {
|
const getDetailInfo = (row) => {
|
||||||
detailUniqueCode({ id: row.id }).then((res) => {
|
detailUniqueCode({ id: row.id }).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
materialList.value = [{ ...res.data.material, ...getDetail(res.data.material.wornMaterial), qrCode: res.data.qrCode, code: res.data.code,qrCodeMark:res.data.remark }]
|
materialList.value.material = [{ ...res.data.material, ...getDetail(res.data.material.wornMaterial), qrCode: res.data.qrCode, code: res.data.code, uniqueCodeRemark: res.data.remark }]
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
modalRef.value.open()
|
modalRef.value.open()
|
||||||
}, 300)
|
}, 300)
|
||||||
@@ -159,6 +162,7 @@ const getDetailInfo = (row) => {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep.qrCodeModal {
|
::v-deep.qrCodeModal {
|
||||||
.uv-modal__content {
|
.uv-modal__content {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
export const getTypeParentNames = (val) => {
|
export const getTypeParentNames = (val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
let value = val.replace("/", ",");
|
let value = val.replace(/\//g, ",");
|
||||||
const arr = `${value}`.split(",");
|
const arr = `${value}`.split(",");
|
||||||
return arr[arr?.length - 1];
|
return arr[0];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -49,6 +49,7 @@ export const getDetail = (info) => {
|
|||||||
description: info.description,
|
description: info.description,
|
||||||
weight: info.weight,
|
weight: info.weight,
|
||||||
kgFactor: info.kgFactor,
|
kgFactor: info.kgFactor,
|
||||||
|
materialId:info.id,//物料id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BIN
static/edit.png
Normal file
BIN
static/edit.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
BIN
static/printer.png
Normal file
BIN
static/printer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
@@ -11,11 +11,11 @@
|
|||||||
.subTitle {
|
.subTitle {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #999;
|
color: #999;
|
||||||
margin-top: 14rpx;
|
margin-top: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag {
|
.tag {
|
||||||
margin-top: 14rpx;
|
margin-top: 8rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -27,7 +27,6 @@
|
|||||||
.uni-tag {
|
.uni-tag {
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.remark {
|
.remark {
|
||||||
@@ -37,20 +36,16 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
p {
|
p {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin-top: 16rpx;
|
margin-top: 8rpx;
|
||||||
}
|
}
|
||||||
span {
|
span {
|
||||||
color: #616161;
|
color: #616161;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.qrCode{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
.status {
|
.status {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #616161;
|
color: #616161;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
.flex-center {
|
.flex-center {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -64,8 +59,8 @@
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background-color: #409EFF !important;
|
background-color: #409eff !important;
|
||||||
border-color: #409EFF !important;
|
border-color: #409eff !important;
|
||||||
height: 60rpx;
|
height: 60rpx;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -76,6 +71,155 @@
|
|||||||
.mt-8 {
|
.mt-8 {
|
||||||
margin-top: 8rpx;
|
margin-top: 8rpx;
|
||||||
}
|
}
|
||||||
|
.mb-16 {
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
.mb-4 {
|
||||||
|
margin-bottom: 4rpx;
|
||||||
|
}
|
||||||
|
.mb-6 {
|
||||||
|
margin-bottom: 6rpx;
|
||||||
|
}
|
||||||
|
.mb-2 {
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
.mt-16 {
|
.mt-16 {
|
||||||
margin-top: 16rpx;
|
margin-top: 16rpx;
|
||||||
}
|
}
|
||||||
|
.mr-8 {
|
||||||
|
margin-right: 8rpx;
|
||||||
|
}
|
||||||
|
.mr-16 {
|
||||||
|
margin-right: 16rpx;
|
||||||
|
}
|
||||||
|
.ml-8 {
|
||||||
|
margin-left: 8rpx;
|
||||||
|
}
|
||||||
|
.ml-16 {
|
||||||
|
margin-left: 16rpx;
|
||||||
|
}
|
||||||
|
.ml-24 {
|
||||||
|
margin-left: 24rpx;
|
||||||
|
}
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.align-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.justify-center {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.justify-between {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.f-12 {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.grey {
|
||||||
|
color: #696969;
|
||||||
|
}
|
||||||
|
.tag-error {
|
||||||
|
padding: 4px 6px;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: inline-block;
|
||||||
|
height: 20px;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #e43d33;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-box {
|
||||||
|
background-color: #fff;
|
||||||
|
// 标题
|
||||||
|
.title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
// 副标题
|
||||||
|
.subTitle {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.uniqueCode {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
// 标签
|
||||||
|
.tag-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.quantity-form {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.uni-forms-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.uni-easyinput__content-input{
|
||||||
|
height: 25px;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unit {
|
||||||
|
margin-left: 8rpx;
|
||||||
|
font-size: 12px;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.remark-row {
|
||||||
|
.uni-forms-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-forms-item__label {
|
||||||
|
height: 25px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-easyinput,
|
||||||
|
.uni-easyinput__content,
|
||||||
|
.uni-input-input {
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-disabled {
|
||||||
|
background-color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-input-input:disabled {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.uni-easyinput__content-input {
|
||||||
|
.uni-input-wrapper {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.uni-input-placeholder {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.text {
|
||||||
|
height: 100%;
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
color: #616161;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.status {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #616161;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
15
yarn.lock
15
yarn.lock
@@ -341,6 +341,11 @@ commander@^2.20.0:
|
|||||||
resolved "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz"
|
resolved "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz"
|
||||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||||
|
|
||||||
|
dayjs@^1.11.20:
|
||||||
|
version "1.11.20"
|
||||||
|
resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.20.tgz"
|
||||||
|
integrity sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==
|
||||||
|
|
||||||
detect-libc@^2.0.3:
|
detect-libc@^2.0.3:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz"
|
resolved "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz"
|
||||||
@@ -504,6 +509,11 @@ loader-utils@^2.0.0:
|
|||||||
emojis-list "^3.0.0"
|
emojis-list "^3.0.0"
|
||||||
json5 "^2.1.2"
|
json5 "^2.1.2"
|
||||||
|
|
||||||
|
lodash@^4.17.23:
|
||||||
|
version "4.17.23"
|
||||||
|
resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.23.tgz"
|
||||||
|
integrity sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==
|
||||||
|
|
||||||
merge-stream@^2.0.0:
|
merge-stream@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz"
|
resolved "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz"
|
||||||
@@ -536,6 +546,11 @@ node-releases@^2.0.27:
|
|||||||
resolved "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.36.tgz"
|
resolved "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.36.tgz"
|
||||||
integrity sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==
|
integrity sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==
|
||||||
|
|
||||||
|
numeral@^2.0.6:
|
||||||
|
version "2.0.6"
|
||||||
|
resolved "https://registry.npmmirror.com/numeral/-/numeral-2.0.6.tgz"
|
||||||
|
integrity sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA==
|
||||||
|
|
||||||
picocolors@^1.1.1:
|
picocolors@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz"
|
resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz"
|
||||||
|
|||||||
Reference in New Issue
Block a user