Commit 64a41ec5 by qinjianhui

Merge branch 'dev' into 'master'

Dev

See merge request !69
parents 0175906b 94c98ec1
...@@ -32,6 +32,7 @@ declare module 'vue' { ...@@ -32,6 +32,7 @@ declare module 'vue' {
ElImage: typeof import('element-plus/es')['ElImage'] ElImage: typeof import('element-plus/es')['ElImage']
ElInput: typeof import('element-plus/es')['ElInput'] ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElLink: typeof import('element-plus/es')['ElLink']
ElMenu: typeof import('element-plus/es')['ElMenu'] ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption'] ElOption: typeof import('element-plus/es')['ElOption']
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"element-plus": "^2.6.0", "element-plus": "^2.6.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"luxon": "^3.7.1",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"splitpanes": "^3.1.5", "splitpanes": "^3.1.5",
"vue": "^3.4.19", "vue": "^3.4.19",
...@@ -26,6 +27,7 @@ ...@@ -26,6 +27,7 @@
"xlsx": "^0.18.5" "xlsx": "^0.18.5"
}, },
"devDependencies": { "devDependencies": {
"@types/luxon": "^3.7.1",
"@types/splitpanes": "^2.2.6", "@types/splitpanes": "^2.2.6",
"@typescript-eslint/eslint-plugin": "^7.1.1", "@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1", "@typescript-eslint/parser": "^7.1.1",
...@@ -1989,6 +1991,13 @@ ...@@ -1989,6 +1991,13 @@
"@types/lodash": "*" "@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": { "node_modules/@types/semver": {
"version": "7.7.0", "version": "7.7.0",
"resolved": "https://registry.npmmirror.com/@types/semver/-/semver-7.7.0.tgz", "resolved": "https://registry.npmmirror.com/@types/semver/-/semver-7.7.0.tgz",
...@@ -4882,6 +4891,15 @@ ...@@ -4882,6 +4891,15 @@
"yallist": "^3.0.2" "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": { "node_modules/magic-string": {
"version": "0.30.17", "version": "0.30.17",
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz", "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz",
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"element-plus": "^2.6.0", "element-plus": "^2.6.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"luxon": "^3.7.1",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"splitpanes": "^3.1.5", "splitpanes": "^3.1.5",
"vue": "^3.4.19", "vue": "^3.4.19",
...@@ -28,6 +29,7 @@ ...@@ -28,6 +29,7 @@
"xlsx": "^0.18.5" "xlsx": "^0.18.5"
}, },
"devDependencies": { "devDependencies": {
"@types/luxon": "^3.7.1",
"@types/splitpanes": "^2.2.6", "@types/splitpanes": "^2.2.6",
"@typescript-eslint/eslint-plugin": "^7.1.1", "@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1", "@typescript-eslint/parser": "^7.1.1",
......
...@@ -12,9 +12,7 @@ export function getLogisticsCompanyList() { ...@@ -12,9 +12,7 @@ export function getLogisticsCompanyList() {
} }
// 获取客户 // 获取客户
export function getUserMarkList() { export function getUserMarkList() {
return axios.get<never, BaseRespData<string[]>>( return axios.get<never, BaseRespData<string[]>>('dbDiyUser/getUserMarkList')
'dbDiyUser/getUserMarkList',
)
} }
// 获取用户 // 获取用户
...@@ -35,3 +33,17 @@ export function uploadFileApi(data: FormData) { ...@@ -35,3 +33,17 @@ export function uploadFileApi(data: FormData) {
data, 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}`,
)
}
<template> <template>
<div class="log-list"> <div class="log-list">
<div <div v-for="l in logList" :key="l.id" class="log-item flex">
v-for="l in logList"
:key="l.id"
class="log-item flex"
>
<div class="log-item-icon"> <div class="log-item-icon">
<Icon name="a-2labadianji3x" /> <Icon name="a-2labadianji3x" />
</div> </div>
<div class="log-item-time"> <div class="log-item-time">
<span>{{ l.createTime }}</span> <span>{{ l.local && `${l.local}:` }}{{ l.createTime }}</span>
</div> </div>
<div v-if="l.employeeName" class="log-item-name"> <div v-if="l.employeeName" class="log-item-name">
<span>{{ l.employeeName }}</span> <span>{{ l.employeeName }}</span>
...@@ -45,7 +41,7 @@ defineProps({ ...@@ -45,7 +41,7 @@ defineProps({
} }
.log-item-time { .log-item-time {
width: 140px; // width: 220px;
} }
.log-item-name { .log-item-name {
......
...@@ -113,12 +113,15 @@ ...@@ -113,12 +113,15 @@
</div> </div>
<!-- 右侧工具栏 --> <!-- 右侧工具栏 -->
<div class="tool_warper"> <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 <div
title="格式工具" title="获取物流面单"
style="cursor: pointer" class="tool-item"
@click="formatDrawer = true" @click="getLogisticDrawer = true"
> >
<img src="../assets/images/brush-no.png" width="24" height="24" /> <img src="../assets/images/package.png" width="24" height="24" />
</div> </div>
</div> </div>
</div> </div>
...@@ -196,12 +199,22 @@ ...@@ -196,12 +199,22 @@
</div> </div>
<template #footer> <template #footer>
<span style="display: flex; justify-content: center"> <span style="display: flex; justify-content: center">
<el-button size="medium" @click="formatDrawer = false"> <el-button @click="formatDrawer = false"> 取 消 </el-button>
取 消 <el-button type="primary" @click="copy"> 拷 贝 </el-button>
</el-button> </span>
<el-button size="medium" type="primary" @click="copy"> </template>
拷 贝 </el-drawer>
</el-button> <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> </span>
</template> </template>
</el-drawer> </el-drawer>
...@@ -230,6 +243,9 @@ import userUserStore from '@/store/user' ...@@ -230,6 +243,9 @@ import userUserStore from '@/store/user'
import type { FormRules } from 'element-plus' import type { FormRules } from 'element-plus'
import { useValue } from '@/utils/hooks/useValue' import { useValue } from '@/utils/hooks/useValue'
import { changePasswordApi } from '@/api/auth' import { changePasswordApi } from '@/api/auth'
import { getLogisticUSApi, getLogisticCNApi } from '@/api/common'
import { filePath } from '@/api/axios'
import { ElMessage } from 'element-plus'
interface MenuItem { interface MenuItem {
index: string index: string
id: number id: number
...@@ -255,8 +271,10 @@ const userStore = userUserStore() ...@@ -255,8 +271,10 @@ const userStore = userUserStore()
const userInfo = userStore.user const userInfo = userStore.user
const dialogVisible = ref(false) const dialogVisible = ref(false)
const formatDrawer = ref(false) const formatDrawer = ref(false)
const getLogisticDrawer = ref(false)
const textareaT = ref('') const textareaT = ref('')
const newTextareaT = ref('') const newTextareaT = ref('')
const content = ref('')
// 密码form // 密码form
const [passwordForm, resetPasswordForm] = useValue<PasswordForm>( const [passwordForm, resetPasswordForm] = useValue<PasswordForm>(
{} as PasswordForm, {} as PasswordForm,
...@@ -470,6 +488,7 @@ const confimTools = (v: string) => { ...@@ -470,6 +488,7 @@ const confimTools = (v: string) => {
} }
} }
// 复制
const copy = () => { const copy = () => {
const oInput = document.createElement('input') const oInput = document.createElement('input')
oInput.value = newTextareaT.value oInput.value = newTextareaT.value
...@@ -485,6 +504,40 @@ const copy = () => { ...@@ -485,6 +504,40 @@ const copy = () => {
}) })
} }
// 获取物流面单
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( watch(
() => route.path, () => route.path,
...@@ -646,4 +699,16 @@ onUnmounted(() => { ...@@ -646,4 +699,16 @@ onUnmounted(() => {
top: 15%; top: 15%;
right: 40px; right: 40px;
} }
::v-deep(.get-logistic-drawer.el-drawer.rtl) {
height: 20% !important;
top: 35% !important;
}
.tool-item {
width: 24px;
height: 24px;
cursor: pointer;
margin-bottom: 10px;
}
</style> </style>
...@@ -200,6 +200,7 @@ export interface LogListData { ...@@ -200,6 +200,7 @@ export interface LogListData {
employeeName?: string employeeName?: string
description?: string description?: string
createTime?: string createTime?: string
local?: string
} }
export interface QaData { export interface QaData {
......
...@@ -144,6 +144,7 @@ export interface LogListData { ...@@ -144,6 +144,7 @@ export interface LogListData {
description: string description: string
deleteContent: string deleteContent: string
createTime: string createTime: string
local?: string
} }
export interface ProductionClient { export interface ProductionClient {
code?: string code?: string
......
import { get } from 'lodash-es' import { get } from 'lodash-es'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { DateTime } from 'luxon'
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
export function val<T>(data: T, key: string | ((data: T) => any)) { export function val<T>(data: T, key: string | ((data: T) => any)) {
if (typeof key === 'function') return key(data) if (typeof key === 'function') return key(data)
...@@ -20,3 +21,22 @@ export function copyText(text: string) { ...@@ -20,3 +21,22 @@ export function copyText(text: string) {
document.body.removeChild(oInput) document.body.removeChild(oInput)
ElMessage.success('复制成功') 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')
}
...@@ -36,6 +36,7 @@ import { showConfirm } from '@/utils/ui' ...@@ -36,6 +36,7 @@ import { showConfirm } from '@/utils/ui'
import { isArray, isString } from '@/utils/validate' import { isArray, isString } from '@/utils/validate'
import ResultInfo from '../podUs/components/ResultInfo.vue' import ResultInfo from '../podUs/components/ResultInfo.vue'
import { filePath } from '@/api/axios' import { filePath } from '@/api/axios'
import { convertToChinaTime } from '@/utils/index'
import { useValue } from '@/utils/hooks/useValue' import { useValue } from '@/utils/hooks/useValue'
...@@ -341,6 +342,19 @@ const pickerOptions = { ...@@ -341,6 +342,19 @@ const pickerOptions = {
return [start, end] 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)
}
},
},
], ],
} }
...@@ -514,7 +528,13 @@ const operationLog = async () => { ...@@ -514,7 +528,13 @@ const operationLog = async () => {
if (currentRowId.value) { if (currentRowId.value) {
const res = await getOperationLogApi(currentRowId.value as number) const res = await getOperationLogApi(currentRowId.value as number)
if (res.code !== 200) return 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) { } catch (e) {
console.error(e) console.error(e)
...@@ -620,6 +640,17 @@ const getOrderByIdApi = async (type: string) => { ...@@ -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 = () => { const resultConfirm = () => {
search() search()
loadTabData() loadTabData()
...@@ -1000,6 +1031,29 @@ onMounted(() => { ...@@ -1000,6 +1031,29 @@ onMounted(() => {
</TableView> </TableView>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="操作日志" @tab-click="operationLog"> <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 <LogList
v-loading="logLoading" v-loading="logLoading"
:log-list="logList" :log-list="logList"
......
...@@ -1128,10 +1128,13 @@ const handleWarehouseChange = (value: string | number) => { ...@@ -1128,10 +1128,13 @@ const handleWarehouseChange = (value: string | number) => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: calc(100% - 60px); height: calc(100% - 60px);
width: calc(100% - 40px);
margin-left: 0;
} }
.el-dialog__body { .el-dialog__body {
flex: 1; flex: 1;
overflow: hidden; overflow: hidden;
display: flex;
} }
} }
</style> </style>
...@@ -1892,6 +1892,32 @@ ...@@ -1892,6 +1892,32 @@
width="1000px" width="1000px"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<template #header="{ titleId, titleClass }">
<div style="display: flex" class="my-header">
<div :id="titleId" :class="titleClass">操作日志</div>
<!-- <el-button
type="primary"
size="small"
style="margin-left: 10px"
@click="changeChinaTime"
>转换为中国时间</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>
</template>
<LogList :log-list="logList" /> <LogList :log-list="logList" />
</el-dialog> </el-dialog>
<FastProduction <FastProduction
...@@ -2172,6 +2198,7 @@ ...@@ -2172,6 +2198,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { getUserMarkList } from '@/api/common' import { getUserMarkList } from '@/api/common'
// import { AnyObject } from '@/types/api/warehouse' // import { AnyObject } from '@/types/api/warehouse'
import { convertToChinaTime } from '@/utils/index'
import { import {
InfoFilled, InfoFilled,
ArrowDown, ArrowDown,
...@@ -2462,6 +2489,19 @@ const pickerOptions = { ...@@ -2462,6 +2489,19 @@ const pickerOptions = {
return [start, end] 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)
}
},
},
], ],
} }
const filteredImages = (imageAry: string | null) => { const filteredImages = (imageAry: string | null) => {
...@@ -3724,7 +3764,14 @@ const operationLog = async (id: number, e: MouseEvent | null) => { ...@@ -3724,7 +3764,14 @@ const operationLog = async (id: number, e: MouseEvent | null) => {
try { try {
const res = await getOperationLogApi(id) const res = await getOperationLogApi(id)
if (res.code !== 200) return if (res.code !== 200) return
logList.value = res.data logList.value = res.data.map((el) => {
return {
...el,
local: 'BeiJing',
}
})
tempChinaLogs.value = [...logList.value]
logVisible.value = true logVisible.value = true
} catch (e) { } catch (e) {
console.error(e) console.error(e)
...@@ -4755,6 +4802,17 @@ const statusPush = async () => { ...@@ -4755,6 +4802,17 @@ const statusPush = async () => {
} }
} }
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],
}
})
}
useRouter().beforeEach((to, from, next) => { useRouter().beforeEach((to, from, next) => {
handleBeforeRouteLeave(to, from, next) handleBeforeRouteLeave(to, from, next)
}) })
......
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