Commit f1e2985d by wuqian

Merge remote-tracking branch 'origin/dev' into new-pod-cn

parents 57f7f0f1 7acfef98
......@@ -32,6 +32,7 @@ declare module 'vue' {
ElImage: typeof import('element-plus/es')['ElImage']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElLink: typeof import('element-plus/es')['ElLink']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption']
......
......@@ -16,6 +16,7 @@
"dayjs": "^1.11.13",
"element-plus": "^2.6.0",
"lodash-es": "^4.17.21",
"luxon": "^3.7.1",
"pinia": "^2.1.7",
"splitpanes": "^3.1.5",
"vue": "^3.4.19",
......@@ -26,6 +27,7 @@
"xlsx": "^0.18.5"
},
"devDependencies": {
"@types/luxon": "^3.7.1",
"@types/splitpanes": "^2.2.6",
"@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1",
......@@ -1989,6 +1991,13 @@
"@types/lodash": "*"
}
},
"node_modules/@types/luxon": {
"version": "3.7.1",
"resolved": "https://registry.npmmirror.com/@types/luxon/-/luxon-3.7.1.tgz",
"integrity": "sha512-H3iskjFIAn5SlJU7OuxUmTEpebK6TKB8rxZShDslBMZJ5u9S//KM1sbdAisiSrqwLQncVjnpi2OK2J51h+4lsg==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/semver": {
"version": "7.7.0",
"resolved": "https://registry.npmmirror.com/@types/semver/-/semver-7.7.0.tgz",
......@@ -4882,6 +4891,15 @@
"yallist": "^3.0.2"
}
},
"node_modules/luxon": {
"version": "3.7.1",
"resolved": "https://registry.npmmirror.com/luxon/-/luxon-3.7.1.tgz",
"integrity": "sha512-RkRWjA926cTvz5rAb1BqyWkKbbjzCGchDUIKMCUvNi17j6f6j8uHGDV82Aqcqtzd+icoYpELmG3ksgGiFNNcNg==",
"license": "MIT",
"engines": {
"node": ">=12"
}
},
"node_modules/magic-string": {
"version": "0.30.17",
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz",
......
......@@ -18,6 +18,7 @@
"dayjs": "^1.11.13",
"element-plus": "^2.6.0",
"lodash-es": "^4.17.21",
"luxon": "^3.7.1",
"pinia": "^2.1.7",
"splitpanes": "^3.1.5",
"vue": "^3.4.19",
......@@ -28,6 +29,7 @@
"xlsx": "^0.18.5"
},
"devDependencies": {
"@types/luxon": "^3.7.1",
"@types/splitpanes": "^2.2.6",
"@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1",
......
......@@ -12,9 +12,7 @@ export function getLogisticsCompanyList() {
}
// 获取客户
export function getUserMarkList() {
return axios.get<never, BaseRespData<string[]>>(
'dbDiyUser/getUserMarkList',
)
return axios.get<never, BaseRespData<string[]>>('dbDiyUser/getUserMarkList')
}
// 获取用户
......@@ -35,3 +33,17 @@ export function uploadFileApi(data: FormData) {
data,
)
}
// 获取物流面单 US
export function getLogisticUSApi(content: string) {
return axios.get<never, BaseRespData<{ documentUrl: string }>>(
`factory/podJomallOrderUs/getDocument?content=${content}`,
)
}
// 获取物流面单 CN
export function getLogisticCNApi(content: string) {
return axios.get<never, BaseRespData<{ documentUrl: string }>>(
`factory/podJomallOrder/getDocument?content=${content}`,
)
}
......@@ -196,9 +196,9 @@ export function getPodJomallOrderByFactoryNumber(factoryOrderNumber: string) {
return axios.get<never, BaseRespData<OrderData>>(
'factory/podJomallOrder/getPodJomallOrderByFactoryNumber',
{
params:{
factoryOrderNumber
}
params: {
factoryOrderNumber,
},
},
)
}
......@@ -247,3 +247,9 @@ export function completeDeliveryApi(
{ productIdList, ...data },
)
}
export function exportStatementApi(data: SearchForm, status: string) {
return axios.post<never, BaseRespData<never>>(
'factory/podJomallOrder/exportPodJomallReconciliation',
{ ...data, status },
)
}
......@@ -472,7 +472,7 @@ export function batchDownloadDownloadApi(params: { id: number; type: string }) {
}
// 批量下载 删除
export function batchDownloadDeleteApi(params: { id: number }) {
export function batchDownloadDeleteApi(params: { ids?: string }) {
return axios.get<never, BaseRespData<never>>(
`factory/podBatchDownload/delete`,
{
......@@ -526,3 +526,21 @@ export function rejectToApi(params: {
params,
)
}
// 状态推送
export function statusPushApi(params: (string | number)[]) {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderUs/statusPush`,
params,
)
}
// 完成发货
export function completeDeliveryApi(params: {
orderIdList: (string | number)[]
}) {
return axios.post<never, BaseRespData<never>>(
`factory/podJomallOrderUs/completeDelivery`,
params,
)
}
<template>
<div class="log-list">
<div
v-for="l in logList"
:key="l.id"
class="log-item flex"
>
<div v-for="l in logList" :key="l.id" class="log-item flex">
<div class="log-item-icon">
<Icon name="a-2labadianji3x" />
</div>
<div class="log-item-time">
<span>{{ l.createTime }}</span>
<span>{{ l.local && `${l.local}:` }}{{ l.createTime }}</span>
</div>
<div v-if="l.employeeName" class="log-item-name">
<span>{{ l.employeeName }}</span>
......@@ -45,7 +41,7 @@ defineProps({
}
.log-item-time {
width: 140px;
// width: 220px;
}
.log-item-name {
......
......@@ -111,6 +111,19 @@
<ArrowRight />
</el-icon>
</div>
<!-- 右侧工具栏 -->
<div class="tool_warper">
<div title="格式工具" class="tool-item" @click="formatDrawer = true">
<img src="../assets/images/brush-no.png" width="24" height="24" />
</div>
<div
title="获取物流面单"
class="tool-item"
@click="getLogisticDrawer = true"
>
<img src="../assets/images/package.png" width="24" height="24" />
</div>
</div>
</div>
<el-dialog
v-model="dialogVisible"
......@@ -157,6 +170,55 @@
</span>
</template>
</el-dialog>
<span>
<el-drawer
v-model="formatDrawer"
class="format-drawer"
title="格式工具"
direction="rtl"
size="45%"
>
<el-input
v-model="textareaT"
style="width: 100%"
:rows="10"
type="textarea"
placeholder="请输入"
@input="confimTools"
/>
<div
style="
margin-top: 10px;
height: 250px;
overflow: auto;
border: 1px solid #ddd;
padding: 10px;
"
>
{{ newTextareaT }}
</div>
<template #footer>
<span style="display: flex; justify-content: center">
<el-button @click="formatDrawer = false"> 取 消 </el-button>
<el-button type="primary" @click="copy"> 拷 贝 </el-button>
</span>
</template>
</el-drawer>
<el-drawer
v-model="getLogisticDrawer"
class="get-logistic-drawer"
title="获取物流面单"
@close="content = ''"
>
<el-input v-model="content" placeholder="请输入单号" clearable />
<template #footer>
<span style="display: flex; justify-content: center">
<el-button @click="getLogisticDrawer = false"> 取 消 </el-button>
<el-button type="primary" @click="getLogistic">查 询</el-button>
</span>
</template>
</el-drawer>
</span>
</template>
<script setup lang="ts">
import {
......@@ -181,6 +243,9 @@ import userUserStore from '@/store/user'
import type { FormRules } from 'element-plus'
import { useValue } from '@/utils/hooks/useValue'
import { changePasswordApi } from '@/api/auth'
import { getLogisticUSApi, getLogisticCNApi } from '@/api/common'
import { filePath } from '@/api/axios'
import { ElMessage } from 'element-plus'
interface MenuItem {
index: string
id: number
......@@ -205,6 +270,11 @@ const menuList = reactive(Menu)
const userStore = userUserStore()
const userInfo = userStore.user
const dialogVisible = ref(false)
const formatDrawer = ref(false)
const getLogisticDrawer = ref(false)
const textareaT = ref('')
const newTextareaT = ref('')
const content = ref('')
// 密码form
const [passwordForm, resetPasswordForm] = useValue<PasswordForm>(
{} as PasswordForm,
......@@ -396,6 +466,78 @@ const ensureActiveTabVisible = () => {
})
}
// 格式工具输入
const confimTools = (v: string) => {
// 先处理结尾的多个空格,只保留一个
let text = v.replace(/\s+$/, ' ')
// 处理开头的多个空格,只保留一个
text = text.replace(/^\s+/, ' ')
// 将多个连续空格替换为单个空格
text = text.replace(/\s+/g, ' ')
// 然后将所有空格和换行符替换为逗号
text = text.replace(/(\s|[\r\n])/g, ',')
// 如果结尾是逗号,则删除
if (text.slice(-1) === ',') {
newTextareaT.value = text.slice(0, -1)
} else {
newTextareaT.value = text
}
}
// 复制
const copy = () => {
const oInput = document.createElement('input')
oInput.value = newTextareaT.value
document.body.appendChild(oInput)
oInput.select() // 选择对象
document.execCommand('Copy') // 执行浏览器复制命令
oInput.className = 'oInput'
oInput.style.display = 'none'
document.body.removeChild(oInput)
ElMessage({
message: '复制成功',
type: 'success',
})
}
// 获取物流面单
const getLogistic = () => {
if (!content.value) {
ElMessage.warning('请输入单号')
return
}
// 按_分割字符串
const parts = content.value.split('_')
// 检查是否有足够的_分隔符
if (parts.length < 4) {
ElMessage.error('单号格式错误,请检查输入')
return
}
// 获取第三个_后面的内容
const thirdPart = parts[3]
if (thirdPart.startsWith('USPSC')) {
// 美国物流
getLogisticUSApi(content.value).then((res) => {
if (res.code === 200) {
window.open(filePath + res.data.documentUrl, '_blank')
}
})
} else if (thirdPart.startsWith('JMPSC')) {
// 中国物流
getLogisticCNApi(content.value).then((res) => {
if (res.code === 200) {
window.open(filePath + res.data.documentUrl, '_blank')
}
})
} else {
ElMessage.error('单号格式错误,请检查输入')
}
}
// 监听路由变化,自动添加标签
watch(
() => route.path,
......@@ -537,4 +679,36 @@ onUnmounted(() => {
display: flex;
align-items: center;
}
.tool_warper {
position: absolute;
top: 50px;
right: 0;
bottom: 0;
width: 40px;
background: #001529;
z-index: 999;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
::v-deep(.el-drawer.rtl) {
height: 650px !important;
right: 40px;
top: calc(50% - 325px) !important;
}
::v-deep(.get-logistic-drawer.el-drawer.rtl) {
height: 200px !important;
top: calc(50% - 100px) !important;
}
.tool-item {
width: 24px;
height: 24px;
cursor: pointer;
margin-bottom: 10px;
}
</style>
......@@ -109,6 +109,28 @@ const router = createRouter({
component: UserPage,
},
{
path: '/system/downloadClient',
meta: {
title: '下载生产客户端',
},
component: () => {},
beforeEnter() {
// 假设你的下载链接是这个
const downloadLink = '/exeFiles/JomallProductionAssistantSetup.exe'
// 创建一个 a 标签来触发下载
const a = document.createElement('a')
a.href = downloadLink
a.download = '生产客户端.exe' // 你可以指定文件名,或者保持为空来自动使用原始文件名
// 不显示 a 标签,直接触发下载
a.style.display = 'none'
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
},
},
{
path: '/system/external-authorisation',
meta: {
title: '外部授权',
......
......@@ -182,6 +182,11 @@ const menu: MenuItem[] = [
label: '用户管理',
},
{
index: '/system/downloadClient',
id: 4,
label: '下载生产客户端',
},
{
index: '/system/external-authorisation',
id: 5,
label: '外部授权',
......
......@@ -200,6 +200,7 @@ export interface LogListData {
employeeName?: string
description?: string
createTime?: string
local?: string
}
export interface QaData {
......
......@@ -144,6 +144,7 @@ export interface LogListData {
description: string
deleteContent: string
createTime: string
local?: string
}
export interface ProductionClient {
code?: string
......
import { get } from 'lodash-es'
import { ElMessage } from 'element-plus'
import { DateTime } from 'luxon'
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function val<T>(data: T, key: string | ((data: T) => any)) {
if (typeof key === 'function') return key(data)
......@@ -20,3 +21,22 @@ export function copyText(text: string) {
document.body.removeChild(oInput)
ElMessage.success('复制成功')
}
/**
* 将本地时间转换为北京时间(自动检测时区)
* @param {string} localTime - 本地时间字符串,格式 YYYY-MM-DD HH:mm:ss
* @returns {string} 北京时间,格式 YYYY-MM-DD HH:mm:ss
*/
export function convertToChinaTime(
timeString: string,
currentZone: string = 'local',
targetZone: string = 'Asia/Shanghai',
) {
// 将输入的时间字符串解析为本地时间,假设输入时间是本地时间
const inputTime = DateTime.fromFormat(timeString, 'yyyy-MM-dd HH:mm:ss', {
zone: currentZone,
})
const chinaTime = inputTime.setZone(targetZone)
return chinaTime.toFormat('yyyy-MM-dd HH:mm:ss')
}
......@@ -76,32 +76,28 @@
<ElFormItem>
<ElButton @click="resetSearchForm">重置</ElButton>
</ElFormItem>
<ElFormItem v-if="nodeId === 10">
<el-button type="primary" @click="confirmOrder">
确认对账单
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeId === 10">
<el-button type="warning" @click="rejectOrder">
驳回
</el-button>
</ElFormItem>
<ElFormItem>
<el-button type="success" @click="exportExcel">
导出
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeId === 30">
<el-button type="danger" @click="auditOrder('archive')">
归档
</el-button>
</ElFormItem>
</ElForm>
</div>
<div class="btn-list">
<el-button
v-if="nodeId === 10"
type="primary"
@click="confirmOrder"
>
确认对账单
</el-button>
<el-button
v-if="nodeId === 10"
type="warning"
@click="rejectOrder"
>
驳回
</el-button>
<el-button type="success" @click="exportExcel"> 导出 </el-button>
<el-button
v-if="nodeId === 30"
type="danger"
@click="auditOrder('archive')"
>
归档
</el-button>
</div>
<div
class="delivery-note-content flex-1 flex-column overflow-hidden"
>
......
......@@ -20,7 +20,7 @@ import NavMenu from '@/components/NavMenu.vue'
.container {
flex: 1;
padding: 0 10px 10px;
padding: 0 50px 10px 10px;
background-color: #f6f6f6;
overflow: hidden;
}
......
......@@ -29,7 +29,7 @@ let timer: number | undefined
const second = ref(5)
const router = useRouter()
props.showBtn &&
(timer = setInterval(() => {
(timer = window.setInterval(() => {
if (second.value === 0) {
clearInterval(timer)
router.go(-1)
......
......@@ -36,6 +36,7 @@ import { showConfirm } from '@/utils/ui'
import { isArray, isString } from '@/utils/validate'
import ResultInfo from '../podUs/components/ResultInfo.vue'
import { filePath } from '@/api/axios'
import { convertToChinaTime } from '@/utils/index'
import { useValue } from '@/utils/hooks/useValue'
......@@ -341,6 +342,19 @@ const pickerOptions = {
return [start, end]
},
},
{
text: '转换中国时间',
value: () => {
console.log(3469, timeRange.value)
if (timeRange.value?.length) {
const end = timeRange.value[1] ?? ''
const start = timeRange.value[0] ?? ''
return [convertToChinaTime(start), convertToChinaTime(end)]
} else {
return getDateRange(0)
}
},
},
],
}
......@@ -420,7 +434,7 @@ const submitExportForm = async () => {
} catch (e) {
exportVisible.value = false
exportLoading.value = false
}
}
}
const handleSizeChange = (pageSize: number) => {
pagination.value.pageSize = pageSize
......@@ -514,7 +528,13 @@ const operationLog = async () => {
if (currentRowId.value) {
const res = await getOperationLogApi(currentRowId.value as number)
if (res.code !== 200) return
logList.value = res.data
logList.value = res.data.map((el) => {
return {
...el,
local: 'BeiJing',
}
})
tempChinaLogs.value = [...logList.value]
}
} catch (e) {
console.error(e)
......@@ -620,6 +640,17 @@ const getOrderByIdApi = async (type: string) => {
}
}
const tempChinaLogs = ref<LogListData[]>([])
function changeChinaTime(zone: string) {
logList.value = tempChinaLogs.value.map((el) => {
return {
...el,
createTime: convertToChinaTime(el.createTime, 'Asia/Shanghai', zone),
local: zone.split('/')[1] === 'Shanghai' ? 'BeiJing' : zone.split('/')[1],
}
})
}
const resultConfirm = () => {
search()
loadTabData()
......@@ -1000,6 +1031,29 @@ onMounted(() => {
</TableView>
</el-tab-pane>
<el-tab-pane label="操作日志" @tab-click="operationLog">
<div>
<el-button
type="primary"
size="small"
@click="changeChinaTime('Asia/Shanghai')"
>转换为中国时间</el-button
>
<el-button
type="primary"
size="small"
style="margin-left: 10px"
@click="changeChinaTime('America/New_York')"
>转换为新泽西时间</el-button
>
<el-button
type="primary"
size="small"
style="margin-left: 10px"
@click="changeChinaTime('America/Los_Angeles')"
>转换为洛杉矶时间</el-button
>
</div>
<LogList
v-loading="logLoading"
:log-list="logList"
......
......@@ -150,111 +150,81 @@
<el-option value="multiple" label="多面"></el-option>
</el-select>
</ElFormItem>
<ElFormItem>
<ElButton type="primary" @click="loadDiffList">查询</ElButton>
</ElFormItem>
</ElForm>
</div>
<div class="header-filter-tab">
<div class="tabs">
<div
v-for="item in tabsNav"
:key="item.status"
class="tabs-node"
:class="item.status === status ? 'tabs-node_active' : ''"
@click="changeTab(item)"
>
<span class="tabs-node_label">{{ item.statusName }}</span>
<span class="tabs-node_count">{{ `(${item.quantity})` }}</span>
</div>
</div>
</div>
<div class="order-content flex-1 flex-column overflow-hidden mt-10">
<div style="margin-bottom: 10px">
<span v-if="status === 'TO_BE_CONFIRMED'" class="item">
<ElFormItem v-if="status === 'TO_BE_CONFIRMED'">
<ElButton type="success" @click="confirmProduce">确认生产</ElButton>
</span>
<span v-if="status === 'IN_PRODUCTION'" class="item">
</ElFormItem>
<ElFormItem v-if="status === 'IN_PRODUCTION'">
<ElButton type="success" dark @click="fastToProduction('快捷生产', 1)"
>快捷生产</ElButton
>
</span>
<span
</ElFormItem>
<ElFormItem
v-if="
status === 'TO_BE_CONFIRMED' ||
status === 'IN_PRODUCTION' ||
status === 'PART_SHIPPING'
['TO_BE_CONFIRMED', 'IN_PRODUCTION', 'PART_SHIPPING'].includes(
status,
)
"
class="item"
>
<ElButton type="primary" dark @click="printManuscript"
>打印生产单</ElButton
>
</span>
<!-- <span v-if="status === 'TO_BE_CONFIRMED'" class="item">-->
<!-- <ElButton type="success" dark @click="exportManuscript"-->
<!-- >导出生产单</ElButton-->
<!-- >-->
<!-- </span>-->
<span class="item">
</ElFormItem>
<ElFormItem>
<ElButton type="warning" @click="addInternalTag"
>添加内部标签</ElButton
>
</span>
<span
</ElFormItem>
<ElFormItem
v-if="
status === 'TO_BE_CONFIRMED' ||
status === 'IN_PRODUCTION' ||
status === 'PART_SHIPPING'
['TO_BE_CONFIRMED', 'IN_PRODUCTION', 'PART_SHIPPING'].includes(
status,
)
"
class="item"
>
<ElButton type="warning" is-dark @click="downloadMaterial">
下载素材</ElButton
>
</span>
<span
</ElFormItem>
<ElFormItem
v-if="
[
'TO_BE_CONFIRMED',
'IN_PRODUCTION',
'PART_SHIPPING',
'WAIT_SHIPMENT'
'WAIT_SHIPMENT',
].includes(status)
"
class="item"
>
<ElButton type="primary" @click="refreshProduct"
>刷新商品信息</ElButton
>
</span>
<span
</ElFormItem>
<ElFormItem
v-if="status === 'WAIT_SHIPMENT' || status === 'PART_SHIPPING'"
class="item"
>
<ElButton type="success" @click="confirmDelivery">发货</ElButton>
</span>
<span v-if="status === 'WAIT_SHIPMENT'" class="item">
</ElFormItem>
<ElFormItem v-if="status === 'WAIT_SHIPMENT'">
<ElButton type="warning" @click="completeDelivery">完成发货</ElButton>
</span>
<span
</ElFormItem>
<ElFormItem
v-if="['TO_BE_CONFIRMED', 'IN_PRODUCTION'].includes(status)"
class="item"
>
<ElButton type="danger" @click="voidedBtn">作废</ElButton>
</span>
<span
v-if="['WAIT_SHIPMENT', 'IN_PRODUCTION'].includes(status)"
class="item"
>
</ElFormItem>
<ElFormItem v-if="['WAIT_SHIPMENT', 'IN_PRODUCTION'].includes(status)">
<ElButton type="warning" is-dark @click="applyForReplacement">
申请补胚</ElButton
>
</span>
<span
</ElFormItem>
<ElFormItem v-if="['COMPLETE'].includes(status)">
<ElButton type="success" @click="toExport"> 导出对账单</ElButton>
</ElFormItem>
<ElFormItem
v-if="['TO_BE_CONFIRMED', 'IN_PRODUCTION'].includes(status)"
class="item"
>
<ElButton
:loading="syncLoading"
......@@ -264,8 +234,24 @@
>
同步素材图</ElButton
>
</span>
</ElFormItem>
</ElForm>
</div>
<div class="header-filter-tab">
<div class="tabs">
<div
v-for="item in tabsNav"
:key="item.status"
class="tabs-node"
:class="item.status === status ? 'tabs-node_active' : ''"
@click="changeTab(item)"
>
<span class="tabs-node_label">{{ item.statusName }}</span>
<span class="tabs-node_count">{{ `(${item.quantity})` }}</span>
</div>
</div>
</div>
<div class="order-content flex-1 flex-column overflow-hidden mt-10">
<template
v-if="
[
......@@ -1070,6 +1056,50 @@
</template>
</el-dialog>
<el-dialog
v-model="exportVisible"
title="导出对账单"
:close-on-click-modal="false"
width="500PX"
>
<div class="margin-top-20">
<ElForm
style="margin: 20px 0"
:model="shipForm"
label-width="120px"
size="small"
>
<ElRow :gutter="20">
<ElFormItem required label="实际交货时间">
<el-date-picker
v-model="exportTime"
:default-time="[
new Date(0, 0, 0, 0, 0, 0),
new Date(0, 0, 0, 23, 59, 59),
]"
placeholder="实际交货时间"
value-format="YYYY-MM-DD HH:mm:ss"
type="datetimerange"
style="width: 280px"
:shortcuts="pickerOptions.shortcuts"
start-placeholder="开始时间"
end-placeholder="结束时间"
clearable
>
</el-date-picker>
</ElFormItem>
</ElRow>
</ElForm>
</div>
<template #footer>
<div class="dialog-footer">
<el-button size="large" @click="exportVisible = false">取消 </el-button>
<el-button size="large" type="primary" @click="exportData"
>导出
</el-button>
</div>
</template>
</el-dialog>
<el-dialog
v-model="logVisible"
title="操作日志"
width="1000px"
......@@ -1196,6 +1226,7 @@ import {
syncSubOrderDesignImages,
applyForReplenishmentApi,
completeDeliveryApi,
exportStatementApi,
} from '@/api/podOrder'
import TableView from '@/components/TableView.vue'
import {
......@@ -1475,7 +1506,40 @@ const openDetail = async (id: number) => {
//showError(e)
}
}
const shipForm = ref({})
const exportVisible = ref(false)
const exportTime = ref<string[]>([])
const toExport = () => {
exportVisible.value = true
exportTime.value = []
}
const exportData = async () => {
if (!exportTime.value || exportTime.value.length === 0) {
return ElMessage.warning('请选择时间')
}
const loading = ElLoading.service({
fullscreen: true,
text: '操作中...',
background: 'rgba(0, 0, 0, 0.3)',
})
const params = {
startTime: exportTime.value[0],
endTime: exportTime.value[1],
...searchForm.value,
// tagIds: searchForm.value.tagIds.length > 0 ? searchForm.value.tagIds : null,
}
try {
const res = await exportStatementApi(params, status.value)
if (res.code !== 200) return
ElMessage.success('导出成功')
window.open(filePath + res.message)
exportVisible.value = false
} catch (e) {
console.error(e)
} finally {
loading.close()
}
}
const saveCompleteShipment = async () => {
try {
await completeShipmentFormRef.value.validate()
......
......@@ -6,7 +6,12 @@
:fullscreen="true"
:close-on-click-modal="false"
@opened="onOpened"
@close="emit('close')"
@close="
() => {
emit('onSuccess')
emit('close')
}
"
>
<div class="detail-div">
<div class="detail-content">
......@@ -313,22 +318,27 @@ const confirmQuery = (len: HistoryDataItem[], i: number) => {
type: 'warning',
})
.then(async () => {
TrackingNumber.value = el.orderNumber
await trackCodeInput()
await setData(el.orderNumber)
ElMessage.success('生产完成')
if (len[i + 1]) {
confirmQuery(len, i + 1)
try {
TrackingNumber.value = el.orderNumber
await trackCodeInput()
await setData(el.orderNumber)
// ElMessage.success('生产完成')
} catch (error) {
console.log(777)
console.log(error)
removeFromHistory()
} finally {
if (len[i + 1]) {
confirmQuery(len, i + 1)
}
}
})
.catch(() => {
const index = historyData.value.findIndex(
(item: HistoryDataItem) => item.orderNumber === el.orderNumber,
)
if (index >= 0) {
historyData.value.splice(index, 1)
localStorage.setItem('historyUsData', JSON.stringify(historyData.value))
}
removeFromHistory()
if (len[i + 1]) {
confirmQuery(len, i + 1)
}
......@@ -336,6 +346,11 @@ const confirmQuery = (len: HistoryDataItem[], i: number) => {
})
}
const removeFromHistory = () => {
historyData.value = []
localStorage.setItem('historyUsData', JSON.stringify(historyData.value))
}
const changeStatus = async () => {
if (!detail.value || Object.keys(detail.value).length <= 1) {
return ElMessage.warning('请扫码生产单号')
......@@ -353,19 +368,46 @@ const setData = async (orderNumber: string) => {
try {
const id = detail.value.id
const podJomallOrderUsId = detail.value.podJomallOrderUsId
await productionQueryApi(id, podJomallOrderUsId)
if (
detail.value?.num !== undefined &&
detail.value?.passNum !== undefined
) {
const { num, passNum } = detail.value
if (num == passNum) {
await showConfirm('该生产单已经完成生产,请勿重复生产', {
confirmButtonText: '确定',
type: 'warning',
})
TrackingNumber.value = ''
isDownloadImage.value = false
trackingNumberRef.value && trackingNumberRef.value.focus()
throw new Error()
} else if (num < passNum) {
await showConfirm(
`生产单号:${detail.value.factorySubOrderNumber} 已经重复生产${
passNum - num
}件,请检查!`,
{
confirmButtonText: '确定',
type: 'warning',
},
)
TrackingNumber.value = ''
isDownloadImage.value = false
trackingNumberRef.value && trackingNumberRef.value.focus()
throw new Error()
} else {
await productionQueryApi(id, podJomallOrderUsId)
ElMessage.success('生产完成')
}
}
console.log(999)
if (orderNumber) {
const index = historyData.value.findIndex(
(el: HistoryDataItem) => el.orderNumber === orderNumber,
)
if (index >= 0) {
// 扫单完成删除
historyData.value.splice(index, 1)
localStorage.setItem('historyUsData', JSON.stringify(historyData.value))
}
removeFromHistory()
}
emit('onSuccess')
playAudio('weight_success')
detail.value = {
id: -1,
......@@ -377,13 +419,19 @@ const setData = async (orderNumber: string) => {
trackingNumberRef.value && trackingNumberRef.value.focus()
} catch (e) {
console.error(e)
if (orderNumber) {
removeFromHistory()
}
detail.value = {
id: -1,
podJomallOrderUsId: -1,
imgList: [] as cardImages[],
}
trackingNumberRef.value && trackingNumberRef.value.focus()
playAudio('weight_search_error')
throw e
// playAudio('weight_search_error')
}
}
......@@ -453,29 +501,32 @@ const trackCodeInput = async () => {
trackingNumberRef.value && trackingNumberRef.value.focus()
return
}
const item = historyData.value.find(
(el: HistoryDataItem) => el.orderNumber === TrackingNumber.value,
)
if (!item) {
// 记录扫单
historyData.value.push({
orderNumber: TrackingNumber.value,
finished: false,
})
localStorage.setItem('historyUsData', JSON.stringify(historyData.value))
}
const orderNumber = TrackingNumber.value
if (isAutoSure.value) {
await setData(
historyData.value[historyData.value.length - 1].orderNumber || '',
)
try {
if (isAutoSure.value) {
await setData(
historyData.value[historyData.value.length - 1]?.orderNumber || '',
)
}
} catch (error) {
console.log(error)
}
// 记录扫单
historyData.value = [
{
orderNumber,
finished: false,
},
]
localStorage.setItem('historyUsData', JSON.stringify(historyData.value))
try {
const res = await getSubOrderBySubOrderNumber(orderNumber)
if (!res.data) {
removeFromHistory()
return ElMessage.error('生产单不存在')
}
const d = JSON.parse(JSON.stringify(res.data))
......@@ -496,11 +547,11 @@ const trackCodeInput = async () => {
download()
}
playAudio('weight_search_success')
trackingNumberRef.value && trackingNumberRef.value.focus()
TrackingNumber.value = ''
} catch (e) {
console.error(e)
console.error(549, e)
trackingNumberRef.value && trackingNumberRef.value.focus()
TrackingNumber.value = ''
}
......
......@@ -1128,10 +1128,13 @@ const handleWarehouseChange = (value: string | number) => {
display: flex;
flex-direction: column;
height: calc(100% - 60px);
width: calc(100% - 40px);
margin-left: 0;
}
.el-dialog__body {
flex: 1;
overflow: hidden;
display: flex;
}
}
</style>
......@@ -79,32 +79,24 @@
<ElFormItem>
<ElButton @click="reset">重置</ElButton>
</ElFormItem>
<ElFormItem v-if="nodeId === 15">
<el-button type="warning" @click="rejectOrder">
驳回
</el-button>
</ElFormItem>
<ElFormItem>
<el-button type="success" @click="exportExcel">
导出</el-button
>
</ElFormItem>
<ElFormItem v-if="nodeId === 30">
<el-button type="danger" @click="auditOrder('archive')">
归档
</el-button>
</ElFormItem>
</ElForm>
</div>
<div class="btn-list">
<!-- <el-button
v-if="nodeId === 10"
type="primary"
@click="confirmOrder()"
>
确认
</el-button> -->
<el-button
v-if="nodeId === 15"
type="warning"
@click="rejectOrder"
>
驳回
</el-button>
<el-button type="success" @click="exportExcel"> 导出</el-button>
<el-button
v-if="nodeId === 30"
type="danger"
@click="auditOrder('archive')"
>
归档
</el-button>
</div>
<div
class="delivery-note-content flex-1 flex-column overflow-hidden"
>
......@@ -1205,8 +1197,8 @@ const submitPodPrice = async () => {
try {
const res = await apiSetCraftData({
id: currentRow.value?.id,
craftTotalPrice:currentRow.value?.craft_total_amount,
recNumber: currentRow.value?.rec_number,
craftTotalPrice: currentRow.value?.craft_total_amount,
recNumber: currentRow.value?.rec_number,
craftPriceList: filteredList,
})
if (res.code !== 200) return
......
......@@ -25,7 +25,6 @@
<div class="search-form">
<ElForm
:model="searchForm"
size="large"
inline
@submit.prevent
@keyup.enter="search"
......@@ -59,12 +58,12 @@
></ElInput>
</ElFormItem> -->
<ElFormItem>
<ElButton type="primary" size="large" @click="search"
<ElButton type="primary" @click="search"
>查询</ElButton
>
</ElFormItem>
<ElFormItem v-if="treeId === '201'">
<el-button size="large" type="danger" @click="reject"
<el-button type="danger" @click="reject"
>驳回</el-button
>
</ElFormItem>
......
......@@ -93,63 +93,53 @@
<ElFormItem>
<ElButton @click="resetSearchForm">重置</ElButton>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
<el-button type="primary" @click="addDialog(1, null)">
新增
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
<el-button type="danger" @click="rejectedInRecord">
驳回
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
<el-button type="danger" @click="handleBatchDelete">
删除
</el-button>
</ElFormItem>
<ElFormItem>
<el-button type="success" @click="handleExport">
导出
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
<el-button type="warning" @click="auditOrder('audit')">
审核
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
<el-button type="success" @click="auditOrder('submitAudit')">
提交审核
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
<el-button type="danger" @click="auditOrder('invalid')">
作废
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'COMPLETED'">
<el-button type="success" @click="auditOrder('archiving')">
归档
</el-button>
</ElFormItem>
<ElFormItem>
<el-button type="primary" @click="printProductTag">
打印库存SKU标签
</el-button>
</ElFormItem>
</ElForm>
</div>
<div class="btn-list">
<el-button
v-if="nodeCode === 'PENDING_SUBMIT'"
type="primary"
@click="addDialog(1, null)"
>
新增
</el-button>
<el-button
v-if="nodeCode === 'PENDING_AUDIT'"
type="danger"
@click="rejectedInRecord"
>
驳回
</el-button>
<el-button
v-if="nodeCode === 'PENDING_SUBMIT'"
type="danger"
@click="handleBatchDelete"
>
删除
</el-button>
<el-button type="success" @click="handleExport"> 导出 </el-button>
<el-button type="primary" @click="printProductTag">
打印库存SKU标签
</el-button>
<el-button
v-if="nodeCode === 'PENDING_AUDIT'"
type="warning"
@click="auditOrder('audit')"
>
审核
</el-button>
<el-button
v-if="nodeCode === 'PENDING_SUBMIT'"
type="success"
@click="auditOrder('submitAudit')"
>
提交审核
</el-button>
<el-button
v-if="nodeCode === 'PENDING_AUDIT'"
type="danger"
@click="auditOrder('invalid')"
>
作废
</el-button>
<el-button
v-if="nodeCode === 'COMPLETED'"
type="success"
@click="auditOrder('archiving')"
>
归档
</el-button>
</div>
<div
class="delivery-note-content flex-1 flex-column overflow-hidden"
>
......@@ -399,7 +389,7 @@
width="500px"
:close-on-click-modal="false"
>
<div class="import-dialog">
<div class="import-dialog">
<div class="import-content">
<UploadExcel
v-model="importedFileUrl"
......@@ -1159,9 +1149,9 @@ const handleLocalImport = async ({
.filter((item) => item.warehouseSku)
if (importedData.length === 0) {
ElMessage.warning('导入数据中没有有效的库存SKU');
importDialogVisible.value = false;
return;
ElMessage.warning('导入数据中没有有效的库存SKU')
importDialogVisible.value = false
return
}
// 2. 提取导入的 SKU 列表
......@@ -1171,10 +1161,10 @@ const handleLocalImport = async ({
const filteredSkusList = await batchAddCommodity(importedSkus)
if (filteredSkusList.length === 0) {
ElMessage.warning('导入的库存SKU已存在或无效');
importedFileUrl.value = path;
importDialogVisible.value = false;
return;
ElMessage.warning('导入的库存SKU已存在或无效')
importedFileUrl.value = path
importDialogVisible.value = false
return
}
// 4. 将备注信息合并到获取到的商品列表中
......
......@@ -93,63 +93,57 @@
<ElFormItem>
<ElButton @click="resetSearchForm">重置</ElButton>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
<el-button type="primary" @click="addDialog(1, null)">
新增
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
<el-button type="danger" @click="rejectedInRecord">
驳回
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
<el-button type="danger" @click="handleBatchDelete">
删除
</el-button>
</ElFormItem>
<ElFormItem>
<el-button type="success" @click="handleExport">
导出</el-button
>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
<el-button type="warning" @click="auditOrder('audit')">
审核
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_SUBMIT'">
<el-button type="success" @click="auditOrder('submitAudit')">
提交审核
</el-button>
</ElFormItem>
<ElFormItem v-if="nodeCode === 'PENDING_AUDIT'">
<el-button type="danger" @click="auditOrder('invalid')">
作废
</el-button>
</ElFormItem>
<ElFormItem>
<el-button type="primary" @click="printProductTag">
打印库存SKU标签
</el-button>
</ElFormItem>
<ElFormItem>
<el-button
v-if="nodeCode === 'COMPLETED'"
type="success"
@click="auditOrder('archiving')"
>
归档
</el-button>
</ElFormItem>
</ElForm>
</div>
<div class="btn-list">
<el-button
v-if="nodeCode === 'PENDING_SUBMIT'"
type="primary"
@click="addDialog(1, null)"
>
新增
</el-button>
<el-button
v-if="nodeCode === 'PENDING_AUDIT'"
type="danger"
@click="rejectedInRecord"
>
驳回
</el-button>
<el-button
v-if="nodeCode === 'PENDING_SUBMIT'"
type="danger"
@click="handleBatchDelete"
>
删除
</el-button>
<el-button type="success" @click="handleExport"> 导出</el-button>
<el-button type="primary" @click="printProductTag">
打印库存SKU标签
</el-button>
<el-button
v-if="nodeCode === 'PENDING_AUDIT'"
type="warning"
@click="auditOrder('audit')"
>
审核
</el-button>
<el-button
v-if="nodeCode === 'PENDING_SUBMIT'"
type="success"
@click="auditOrder('submitAudit')"
>
提交审核
</el-button>
<el-button
v-if="nodeCode === 'PENDING_AUDIT'"
type="danger"
@click="auditOrder('invalid')"
>
作废
</el-button>
<el-button
v-if="nodeCode === 'COMPLETED'"
type="success"
@click="auditOrder('archiving')"
>
归档
</el-button>
</div>
<div
class="delivery-note-content flex-1 flex-column overflow-hidden"
>
......@@ -823,7 +817,7 @@
<script setup lang="ts">
import { ElMessage, ElRadioGroup, ElTree } from 'element-plus'
import { CirclePlusFilled} from '@element-plus/icons-vue'
import { CirclePlusFilled } from '@element-plus/icons-vue'
import splitDiv from '@/components/splitDiv/splitDiv.vue'
import { ElTable } from 'element-plus'
import usePageList from '@/utils/hooks/usePageList'
......@@ -1211,7 +1205,7 @@ const handleLocalImport = async ({
const importedItem = importedData.find(
(item) => item.warehouseSku === skuItem.sku,
)
const target = locationList.value.find((item:InterProductList) => {
const target = locationList.value.find((item: InterProductList) => {
return item.locationCode == importedItem?.locationCode
})
return {
......@@ -1541,7 +1535,7 @@ const addOtherCurrency = async () => {
(item: InterProductList) => item.locationId === arr[i].locationId,
)
if (!arr[i].locationCode) {
arr[i].locationCode =found? found?.locationCode:''
arr[i].locationCode = found ? found?.locationCode : ''
}
}
if (!formId.value) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment