Commit ceca35f3 by linjinhong

Merge remote-tracking branch 'origin/linjinhong' into dev

parents bb414f3a 79716c32
......@@ -16,6 +16,7 @@ declare module 'vue' {
ElCarousel: typeof import('element-plus/es')['ElCarousel']
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
ElCol: typeof import('element-plus/es')['ElCol']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
......
......@@ -137,7 +137,7 @@ export function printPrintOrderApi(orderIds: number[]) {
return axios.post<never, BaseRespData<string>>(
'factory/podJomallOrderUs/printPickPdf',
{
ids: orderIds.join(',')
ids: orderIds.join(','),
},
)
}
......@@ -249,3 +249,24 @@ export function refreshMaterialApi(orderIds: string) {
{ orderIds },
)
}
// 获取跟踪号
export function getTrackingNumberApi(orderIds: (string | number)[]) {
return axios.post<never, BaseRespData<never>>(
'factory/podJomallOrderUs/getTrackingNumber',
orderIds,
)
}
// 获取打印面单
export function getfaceSimplexFileApi(orderIds: (string | number)[]) {
return axios.post<never, BaseRespData<never>>(
'factory/podJomallOrderUs/getfaceSimplexFile',
orderIds,
)
}
// 取消物流订单
export function cancelLogisticsOrderApi(orderIds: (string | number)[]) {
return axios.post<never, BaseRespData<never>>(
'factory/podJomallOrderUs/cancelLogisticsOrder',
orderIds,
)
}
......@@ -127,13 +127,10 @@ export default defineComponent({
return await formRef.value.validate()
}
// 表单验证方法
const clearValidate = async (clearFields?: string[]) => {
const clearValidate = async () => {
if (!formRef.value) return false
if (clearFields) {
return await formRef.value?.clearValidate(clearFields)
} else {
return await formRef.value?.clearValidate()
}
return await formRef.value?.clearValidate()
}
// 重置表单
......
import { get } from 'lodash-es'
import { ElMessage } from 'element-plus'
// 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)
return get(data, key)
}
/**
* @param {*} text
*/
export function copyText(text: string) {
const oInput = document.createElement('input')
oInput.value = text
document.body.appendChild(oInput)
oInput.select() // 选择对象
document.execCommand('Copy') // 执行浏览器复制命令
oInput.className = 'oInput'
oInput.style.display = 'none'
document.body.removeChild(oInput)
ElMessage.success('复制成功')
}
......@@ -6,24 +6,45 @@ import {
ElCheckboxGroup,
ElInput,
} from 'element-plus'
import { usableAllList } from '@/api/logistics'
const styles = {
searchForm: {
position: 'relative',
},
titleBox: {
display: 'flex',
padding: '10px',
padding: '10px 18px',
justifyContent: 'space-between',
alignItems: 'center',
},
checkboxGroup: {
display: 'flex',
padding: '10px',
justifyContent: 'space-between',
justifyContent: 'flex-start',
backgroundColor: '#efefef',
},
} as const
interface ICompanyList {
warehouseName: string
wayList: IwayList[]
}
interface IwayList {
name: string
id: string
}
interface IAllList {
factoryId: number
id: number
name: string
serviceCode: string
siteUrl: string
status: number
uinuinWarehouseId: number | null
updateTime: string
warehouseId: number
warehouseName: string
}
export default defineComponent({
name: 'CustomizeForm',
props: {
......@@ -31,40 +52,105 @@ export default defineComponent({
type: Array as PropType<(string | number)[]>,
default: () => [],
},
companyList: {
type: Array as PropType<IAllList[]>,
default: () => [],
},
},
emits: ['update:modelValue', 'validate'],
setup() {
const companySelectStatus = ref([])
const companyList = ref([{ name: '1', items: [{ name: '1', id: '1' }] }])
emits: ['update:modelValue'],
setup(props, { emit }) {
const companyList = ref<ICompanyList[]>([])
const allList = ref<IAllList[]>([])
const selectedList = ref<(string | number)[]>([])
const logisticsWayId = ref([])
function setCheckAll() {}
async function getAllList() {
try {
const res = await Promise.allSettled([usableAllList()])
res.forEach(
(
item: PromiseSettledResult<{ code: number; data: never[] }>,
index,
) => {
if (item?.status === 'fulfilled') {
if (item.value.code === 200) {
if (index == 0) {
logisticsWayId.value = [...(item.value.data || [])]
}
const waysName = ref('')
watch(
() => props.modelValue,
(newVal) => {
selectedList.value = newVal
},
{
immediate: true,
deep: true,
},
)
watch(
[() => selectedList.value, () => props.companyList],
(newVal) => {
emit('update:modelValue', newVal[0])
allList.value = newVal[1]
companyList.value = transformData(newVal[1])
if (newVal[1]?.length) {
waysName.value = newVal[1]
.filter((item) => {
if (newVal[0].includes(item.id)) {
return item.name
}
}
},
})
.map((item) => item.name)
.join(',')
// emit('waysName', res)
console.log(87, waysName.value)
}
},
{ deep: true, immediate: true },
)
function setCheckAll(company: ICompanyList, event: boolean) {
if (event) {
selectedList.value = [
...selectedList.value,
...company.wayList.map((item) => item.id),
]
} else {
selectedList.value = selectedList.value.filter(
(item) =>
!company.wayList.map((el) => el.id).includes(item as string),
)
console.log(59, logisticsWayId.value)
} catch (error) {
console.log(error)
}
}
onMounted(() => {
getAllList()
const getCompanySelectedStatus = computed(() => {
const statusMap = new Map()
companyList.value.forEach((company: ICompanyList) => {
const allSelected = company.wayList.every((way) =>
selectedList.value.includes(way.id),
)
statusMap.set(company.warehouseName, allSelected)
})
return (company: ICompanyList) => statusMap.get(company.warehouseName)
})
function transformData(data: IAllList[]) {
const warehouseMap = new Map()
for (const item of data) {
const warehouseName = item.warehouseName ?? '未命名仓库'
if (!warehouseMap.has(warehouseName)) {
warehouseMap.set(warehouseName, new Set())
}
warehouseMap.get(warehouseName).add({ name: item.name, id: item.id })
}
const result: {
warehouseName: string
wayList: { name: string; id: string }[]
}[] = []
warehouseMap.forEach((children, parent) => {
result.push({
warehouseName: parent,
wayList: Array.from(children),
})
})
return result
}
return () => (
<ElPopover
width="650px"
......@@ -73,7 +159,11 @@ export default defineComponent({
popper-style={{ padding: 0 }}
v-slots={{
reference: () => (
<ElInput style={{ width: '100%' }} placeholder="请选择物流方式" />
<ElInput
modelValue={waysName.value}
style={{ width: '100%' }}
placeholder="请选择物流方式"
/>
),
}}
>
......@@ -81,10 +171,10 @@ export default defineComponent({
{companyList.value.map((company, index) => (
<div class="companyBox" key={index}>
<div style={styles.titleBox}>
<div class="title">{company.name}</div>
<div class="title">{company.warehouseName}</div>
<ElCheckbox
modelValue={companySelectStatus.value[index]}
onChange={() => setCheckAll()}
modelValue={getCompanySelectedStatus.value(company)}
onChange={(v) => setCheckAll(company, v as boolean)}
class="selectAll"
>
全选
......@@ -96,7 +186,7 @@ export default defineComponent({
onUpdate:modelValue={(value) => (selectedList.value = value)}
style={styles.checkboxGroup}
>
{company.items.map((item) => (
{company.wayList.map((item) => (
<ElCheckbox
label={item.name}
value={item.id}
......
......@@ -14,6 +14,7 @@
<CustomizeTable
v-model="tableData"
:config="tableConfig"
align="center"
@getCheckboxRecords="handleCheckboxRecords"
></CustomizeTable>
</div>
......@@ -76,6 +77,7 @@ import {
updateLogisticsCustomsRule,
deleteLogisticsCustomsRule,
getLogisticsLog,
usableAllList,
} from '@/api/logistics'
import SearchForm from '@/components/SearchForm.tsx'
......@@ -91,6 +93,8 @@ import { AddDeclarationRuleObj } from './types/declarationRule'
import { Edit, Delete, List } from '@element-plus/icons-vue'
import { ISeachFormConfig } from '@/types/searchType'
import LogisticsWaySelect from './components/LogisticsWaySelect.tsx'
import { TableColumn } from '@/components/VxeTable'
const [searchForm] = useValue({})
const [editForm, resetEditForm] = useValue<AddDeclarationRuleObj>({
type: 1,
......@@ -172,11 +176,16 @@ const formConfig = computed<IFormConfig[]>(() => [
],
},
{
prop: 'logisticsWay',
prop: 'logisticsWayId',
type: 'select',
label: '物流方式',
render: () => {
return <LogisticsWaySelect></LogisticsWaySelect>
return (
<LogisticsWaySelect
v-model={editForm.value.logisticsWayId}
companyList={logisticsWayId.value}
></LogisticsWaySelect>
)
},
rules: [
......@@ -202,15 +211,15 @@ const formConfig = computed<IFormConfig[]>(() => [
if (value === 2) {
editForm.value.fixedValue = ''
editForm.value.fixedWeight = ''
editFormRef.value?.clearValidate()
} else {
editForm.value.orderPercent = ''
editForm.value.valueUp = ''
editForm.value.weightPercent = ''
editForm.value.weightUp = ''
editFormRef.value?.clearValidate()
}
editFormRef.value?.refashConfig(mapData.value.get(value) as string[])
editFormRef.value?.clearValidate()
console.log(221, editForm.value)
},
},
rules: [
......@@ -234,6 +243,7 @@ const formConfig = computed<IFormConfig[]>(() => [
{
required: true,
message: '请输入固定金额',
trigger: 'blur',
},
],
},
......@@ -251,6 +261,7 @@ const formConfig = computed<IFormConfig[]>(() => [
{
required: true,
message: '请输入固定重量',
trigger: 'blur',
},
],
},
......@@ -261,6 +272,7 @@ const formConfig = computed<IFormConfig[]>(() => [
isIncludeProp: true,
attrs: {
placeholder: '请输入金额百分比',
trigger: 'blur',
hasSuffix: true,
suffix: '%',
},
......@@ -268,6 +280,7 @@ const formConfig = computed<IFormConfig[]>(() => [
{
required: true,
message: '请输入金额百分比',
trigger: 'blur',
},
],
},
......@@ -286,6 +299,7 @@ const formConfig = computed<IFormConfig[]>(() => [
{
required: true,
message: '请输入申报价值上限',
trigger: 'blur',
},
],
},
......@@ -303,6 +317,7 @@ const formConfig = computed<IFormConfig[]>(() => [
{
required: true,
message: '请输入重量百分比',
trigger: 'blur',
},
],
},
......@@ -320,6 +335,7 @@ const formConfig = computed<IFormConfig[]>(() => [
{
required: true,
message: '请输入申报重量上限',
trigger: 'blur',
},
],
},
......@@ -336,7 +352,7 @@ const formConfig = computed<IFormConfig[]>(() => [
},
])
const tableConfig = ref([
const tableConfig = ref<TableColumn[]>([
{
prop: 'name',
label: '规则名称',
......@@ -349,6 +365,35 @@ const tableConfig = ref([
{
prop: 'type',
label: '申报类型',
render: {
default: ({ row }: { row: AddDeclarationRuleObj }) => (
<span>{row.type === 1 ? '固定' : '比例'}</span>
),
},
},
{
prop: 'logisticsWayId',
label: '物流方式',
attrs: {
width: 300,
},
render: {
default: ({ row }: { row: AddDeclarationRuleObj }) =>
row.logisticsWay ? (
<span>
{logisticsWayId.value
.map((el: { id: number; name: string }) => {
if (row.logisticsWay?.split(',')?.includes(el.id.toString())) {
return el.name
}
})
.filter((el) => el !== undefined)
.join(',')}
</span>
) : (
<span>{''}</span>
),
},
},
{
prop: 'fixedValue',
......@@ -438,6 +483,12 @@ function cancelFn() {
async function editRule(item: AddDeclarationRuleObj) {
try {
editForm.value = { ...item }
console.log(477, item)
editForm.value.logisticsWayId = item.logisticsWay
?.split(',')
.map((el) => Number(el))
dialogVisible.value = true
nextTick(() => {
editFormRef.value?.refashConfig(
......@@ -466,7 +517,7 @@ async function checkData() {
}),
new Promise<AddDeclarationRuleObj>((resolve) => {
const params = { ...editForm.value }
params.logisticsWay = params.logisticsWayId?.join(',')
resolve(params)
}),
])
......@@ -607,30 +658,30 @@ async function showLog(row: AddDeclarationRuleObj) {
}
onMounted(() => {
// getAllList()
getAllList()
})
/**
* @description: 获取物流方式列表
*/
// const logisticsWayId = ref([])
// async function getAllList() {
// try {
// const res = await Promise.allSettled([usableAllList()])
// res.forEach(
// (item: PromiseSettledResult<{ code: number; data: never[] }>, index) => {
// if (item?.status === 'fulfilled') {
// if (item.value.code === 200) {
// if (index == 0) {
// logisticsWayId.value = [...(item.value.data || [])]
// }
// }
// }
// },
// )
// } catch (error) {
// console.log(error)
// }
// }
const logisticsWayId = ref([])
async function getAllList() {
try {
const res = await Promise.allSettled([usableAllList()])
res.forEach(
(item: PromiseSettledResult<{ code: number; data: never[] }>, index) => {
if (item?.status === 'fulfilled') {
if (item.value.code === 200) {
if (index == 0) {
logisticsWayId.value = [...(item.value.data || [])]
}
}
}
},
)
} catch (error) {
console.log(error)
}
}
</script>
<style lang="scss" scoped>
......
......@@ -255,28 +255,28 @@ const formConfig = computed<IFormConfig[]>(() => [
},
],
},
{
prop: 'ruleId',
type: 'select',
label: '申报规则',
fixed: 'last',
attrs: {
placeholder: '请选择申报规则',
label: 'name',
value: 'id',
options: [...(ruleNameList.value || [])],
onChange: (value: { name: string; id: string | number }) => {
editForm.value.ruleRef.ruleId = value.id
editForm.value.ruleRef.ruleName = value.name
},
},
rules: [
{
required: true,
message: '请选择申报规则',
},
],
},
// {
// prop: 'ruleId',
// type: 'select',
// label: '申报规则',
// fixed: 'last',
// attrs: {
// placeholder: '请选择申报规则',
// label: 'name',
// value: 'id',
// options: [...(ruleNameList.value || [])],
// onChange: (value: { name: string; id: string | number }) => {
// editForm.value.ruleRef.ruleId = value.id
// editForm.value.ruleRef.ruleName = value.name
// },
// },
// rules: [
// {
// required: true,
// message: '请选择申报规则',
// },
// ],
// },
{
prop: 'serviceCode',
type: 'input',
......@@ -458,15 +458,15 @@ const tableConfig = ref<TableColumn[]>([
)),
},
},
{
prop: 'status2',
label: '申报规则',
render: {
default: ({ row }) => (
<div>{(row.ruleList as { ruleName: string }[])?.[0]?.ruleName}</div>
),
},
},
// {
// prop: 'status2',
// label: '申报规则',
// render: {
// default: ({ row }) => (
// <div>{(row.ruleList as { ruleName: string }[])?.[0]?.ruleName}</div>
// ),
// },
// },
{
prop: 'siteUrl',
label: '查询网址',
......
......@@ -35,4 +35,6 @@ export interface AddDeclarationRuleObj {
valueUp?: number | string | null
weightPercent?: number | string | null
weightUp?: number | string | null
logisticsWay?: string
logisticsWayId?: (string | number)[]
}
<template>
<el-dialog
title="处理结果"
v-model="resultDialog"
width="600px"
:close-on-click-modal="false"
>
<div style="display: flex">
<el-checkbox
:indeterminate="isIndeterminate"
v-model="checkAll"
@change="checkAllChange"
>
{{ '全选' }}
</el-checkbox>
<el-button
type="success"
style="margin-left: 20px"
@click="resultfilter(true)"
>
{{ '选择正常' }}
</el-button>
<el-button type="danger" @click="resultfilter(false)">
{{ '选择异常' }}
</el-button>
<el-button type="success" @click="copyAllCode(list, 'shopNumber')">
{{ '复制店铺单号' }}
</el-button>
</div>
<div style="height: 50vh; overflow: auto">
<div style="margin: 15px 0"></div>
<el-checkbox-group v-model="selectedList" @change="checkChange">
<div style="display: block" v-for="(item, index) in list" :key="index">
<el-checkbox :label="item.id">
{{ '店铺编号:' + item.shopNumber + ' ' + item.message }}
</el-checkbox>
</div>
</el-checkbox-group>
</div>
<template #footer>
<div style="display: flex; justify-content: flex-end">
<!-- <el-button @click="resultDialog = false"> 取 消 </el-button>
<div style="width: 50px; display: inline-block"></div> -->
<el-button type="primary" @click="confirm"> 确 定 </el-button>
</div>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue'
import { copyText } from '@/utils/index'
interface IList {
id: string | number
shopNumber: string
message: string
status: boolean
}
const props = withDefaults(
defineProps<{
list: IList[]
}>(),
{
list: () => [],
},
)
// 响应式数据
const resultDialog = ref(false)
const isIndeterminate = ref(false)
const checkAll = ref(false)
const selectedList = ref<(string | number)[]>([])
// 显示弹窗
const showDialog = (type: string) => {
console.log(type)
resultDialog.value = true
selectedList.value = []
checkAll.value = false
}
// 全选状态改变
const checkAllChange = (value: boolean) => {
selectedList.value = value ? props.list.map((v) => v.id) : []
isIndeterminate.value = false
}
// 单个选择改变
const checkChange = () => {
const checkedCount = selectedList.value.length
checkAll.value = checkedCount === props.list.length
isIndeterminate.value = checkedCount > 0 && checkedCount < props.list.length
}
// 确认选择
const confirm = () => {
resultDialog.value = false
emits('confirm', selectedList.value)
}
// 结果过滤
const resultfilter = (bool: boolean) => {
const arr = props.list
.filter((item) => item.status === bool)
.map((item) => item.id)
selectedList.value = arr
const checkedCount = arr.length
checkAll.value = checkedCount === props.list.length
isIndeterminate.value = checkedCount > 0 && checkedCount < props.list.length
}
// 复制店铺单号
const copyAllCode = (list: IList[], field: string) => {
const str = list.map((el) => el[field as keyof IList]).join(',')
console.log('复制店铺单号', str)
copyText(str)
}
// 监听弹窗状态
watch(
() => resultDialog.value,
(v) => {
if (v) {
console.log(127)
resultfilter(true)
}
},
)
defineExpose({
showDialog,
})
const emits = defineEmits<{
(e: 'confirm', data: (string | number)[]): void
}>()
</script>
<style lang="scss" scoped></style>
......@@ -171,6 +171,27 @@
<span v-if="status === 'WAIT_SHIPMENT'" class="item">
<ElButton type="warning" @click="printPodOrder"> POD打单 </ElButton>
</span>
<span v-if="status === 'WAIT_SHIPMENT'" class="item">
<ElButton
type="success"
@click="getOrderByIdApi('getTrackingNumber')"
>
获取跟踪号
</ElButton>
</span>
<span v-if="status === 'WAIT_SHIPMENT'" class="item">
<ElButton type="success" @click="getOrderByIdApi('getPrintOrder')">
获取打印面单
</ElButton>
</span>
<span v-if="status === 'WAIT_SHIPMENT'" class="item">
<ElButton
type="success"
@click="getOrderByIdApi('cancelLogisticsOrder')"
>
取消物流订单
</ElButton>
</span>
<span v-if="status === 'STOCK_OUT'" class="item">
<ElButton type="warning" @click="stockOutCheck"> 补货校验 </ElButton>
</span>
......@@ -870,9 +891,16 @@
</div>
</template>
</ElDialog>
<ResultInfo
ref="resultRefs"
:list="resultInfo"
@confirm="resultConfim"
></ResultInfo>
</template>
<script setup lang="ts">
import { getUserMarkList } from '@/api/common'
import { WarningFilled } from '@element-plus/icons-vue'
import {
getCardOrderList,
......@@ -896,6 +924,9 @@ import {
getLogisticsCalculation,
refreshMaterialApi,
LogisticsData,
getTrackingNumberApi,
getfaceSimplexFileApi,
cancelLogisticsOrderApi,
} from '@/api/podUsOrder'
import TableView from '@/components/TableView.vue'
import {
......@@ -921,7 +952,7 @@ import { OrderData } from '@/types/api/podMakeOrder'
import useLodop, { LODOPObject } from '@/utils/hooks/useLodop'
import dayjs from 'dayjs'
import rightMenu from '../pod/rightMenu.vue'
import ResultInfo from './components/ResultInfo.vue'
declare global {
interface Window {
ActiveXObject: {
......@@ -937,6 +968,7 @@ declare global {
}
}
const tabsNav = ref<Tab[]>()
const resultRefs = ref<InstanceType<typeof ResultInfo> | null>(null)
const confirmDialogShow = ref(false)
const confirmData = ref([])
const confirmSelectionData = ref<LogisticsData[]>([])
......@@ -1498,6 +1530,56 @@ const printPodOrder = async () => {
sheetPrinter.value = lodop.GET_PRINTER_NAME(0)
podOrderVisible.value = true
}
/**
* @description: 获取跟踪号、获取打印面单、取消物流订单
*/
const resultInfo = ref([])
const getOrderByIdApi = async (type: string) => {
if (selection.value.length === 0) {
return ElMessage.warning('请选择数据')
}
let message = ''
let Fn
if (type == 'getTrackingNumber') {
message = '获取跟踪号'
Fn = getTrackingNumberApi
} else if (type == 'getPrintOrder') {
message = '获取打印面单'
Fn = getfaceSimplexFileApi
} else if (type === 'cancelLogisticsOrder') {
message = '取消物流订单'
Fn = cancelLogisticsOrderApi
}
try {
await showConfirm(`确定对该订单 ${message}?`, {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
})
const ids = selection.value.map((el) => el.id)
if (Fn) {
const res = await Fn(ids)
console.log(res)
if (res.code === 200) {
resultInfo.value = res.data
resultRefs.value?.showDialog(type)
} else if (res.code === 205) {
window.open(filePath + res.message)
} else {
ElMessage.error(res.message)
}
}
} catch {
return
}
}
const resultConfim = () => {
search()
}
// 添加补货成功行的状态
const stockOutSuccessIds = ref<number[]>([])
......
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