fix(ts): 修复 delete/联合类型/ECharts 等低风险类型错误

- delete 操作符改为解构 rest(afterSale/UserAftersale/OrderUpdatePrice 提交参数)
- v-for 索引、createTime 等联合类型用 Number() 收敛
- ECharts axisLabel.textStyle → axisLabel.color(顺带让标签颜色真正生效)
- AlipayChannelForm 证书上传抽取 readCertFile 并补 UploadRequestHandler 类型
- ExpressForm reset 对齐 DeliveryExpressVO(移除 picUrl、补 code/logo/sort)
ts:check 795 → 768,无新增类型错误
pull/885/MERGE
YunaiV 2026-06-20 10:25:11 -07:00
parent 0970806dca
commit e58fe91a29
13 changed files with 53 additions and 50 deletions

View File

@ -1,6 +1,7 @@
<script lang="tsx"> <script lang="tsx">
import { PropType, nextTick, onBeforeUnmount, onMounted } from 'vue' import { PropType, nextTick, onBeforeUnmount, onMounted } from 'vue'
import { ElMenu, ElScrollbar } from 'element-plus' import { ElMenu, ElScrollbar } from 'element-plus'
import type { MenuInstance } from 'element-plus'
import { useAppStore } from '@/store/modules/app' import { useAppStore } from '@/store/modules/app'
import { usePermissionStore } from '@/store/modules/permission' import { usePermissionStore } from '@/store/modules/permission'
import { useRenderMenuItem } from './components/useRenderMenuItem' import { useRenderMenuItem } from './components/useRenderMenuItem'
@ -63,7 +64,7 @@ export default defineComponent({
const menuWrapRef = ref<HTMLElement>() const menuWrapRef = ref<HTMLElement>()
const menuRef = ref<InstanceType<typeof ElMenu>>() const menuRef = ref<MenuInstance>()
const menuMode = computed( const menuMode = computed(
(): 'vertical' | 'horizontal' => (): 'vertical' | 'horizontal' =>

View File

@ -207,7 +207,7 @@ const getChatConversationList = async () => {
conversationList.value = await ChatConversationApi.getChatConversationMyList() conversationList.value = await ChatConversationApi.getChatConversationMyList()
// 1.2 // 1.2
conversationList.value.sort((a, b) => { conversationList.value.sort((a, b) => {
return b.createTime - a.createTime return Number(b.createTime || 0) - Number(a.createTime || 0)
}) })
// 1.3 // 1.3
if (conversationList.value.length === 0) { if (conversationList.value.length === 0) {
@ -254,7 +254,7 @@ const getConversationGroupByCreateTime = async (list: ChatConversationVO[]) => {
continue continue
} }
// //
const diff = now - conversation.createTime const diff = now - Number(conversation.createTime || 0)
// //
if (diff < oneDay) { if (diff < oneDay) {
groupMap['今天'].push(conversation) groupMap['今天'].push(conversation)

View File

@ -72,7 +72,7 @@
> >
<div v-for="(segment, index) in currentFile.segments" :key="index" class="mb-10px"> <div v-for="(segment, index) in currentFile.segments" :key="index" class="mb-10px">
<div class="text-gray-500 text-12px mb-5px"> <div class="text-gray-500 text-12px mb-5px">
分片-{{ index + 1 }} · {{ segment.contentLength || 0 }} 字符数 · 分片-{{ Number(index) + 1 }} · {{ segment.contentLength || 0 }} 字符数 ·
{{ segment.tokens || 0 }} Token {{ segment.tokens || 0 }} Token
</div> </div>
<div class="bg-white p-10px rounded-md">{{ segment.content }}</div> <div class="bg-white p-10px rounded-md">{{ segment.content }}</div>

View File

@ -29,7 +29,7 @@
</el-descriptions> </el-descriptions>
</ContentWrap> </ContentWrap>
<!-- 表单弹窗添加/修改 --> <!-- 表单弹窗添加/修改 -->
<ProductForm ref="formRef" @success="emit('refresh')" /> <ProductForm ref="formRef" @success="$emit('refresh')" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import ProductForm from '@/views/crm/product/ProductForm.vue' import ProductForm from '@/views/crm/product/ProductForm.vue'

View File

@ -97,7 +97,7 @@
<template #default="{ row }"> <template #default="{ row }">
<template v-if="row.atUserIds?.length"> <template v-if="row.atUserIds?.length">
<span v-for="(userId, idx) in row.atUserIds" :key="userId"> <span v-for="(userId, idx) in row.atUserIds" :key="userId">
<span v-if="idx > 0"></span> <span v-if="Number(idx) > 0"></span>
<template v-if="userId === IM_AT_ALL_USER_ID">@{{ IM_AT_ALL_NICKNAME }}</template> <template v-if="userId === IM_AT_ALL_USER_ID">@{{ IM_AT_ALL_NICKNAME }}</template>
<template v-else> <template v-else>
@{{ row.atUserNicknames?.[idx] || userId }} @{{ row.atUserNicknames?.[idx] || userId }}

View File

@ -214,9 +214,7 @@ const lineChartOptions = reactive<EChartsOption>({
show: false show: false
}, },
axisLabel: { axisLabel: {
textStyle: { color: '#7F8B9C'
color: '#7F8B9C'
}
}, },
splitLine: { splitLine: {
show: true, show: true,
@ -235,9 +233,7 @@ const lineChartOptions = reactive<EChartsOption>({
show: false show: false
}, },
axisLabel: { axisLabel: {
textStyle: { color: '#7F8B9C'
color: '#7F8B9C'
}
}, },
splitLine: { splitLine: {
show: true, show: true,

View File

@ -213,11 +213,9 @@ const getList = async () => {
try { try {
const data = cloneDeep(queryParams) const data = cloneDeep(queryParams)
// //
if (data.status === '0') { const queryData = data.status === '0' ? (({ status: _status, ...rest }) => rest)(data) : data
delete data.status
}
// //
const res = await AfterSaleApi.getAfterSalePage(data) const res = await AfterSaleApi.getAfterSalePage(queryData)
list.value = res.list as AfterSaleApi.TradeAfterSaleVO[] list.value = res.list as AfterSaleApi.TradeAfterSaleVO[]
total.value = res.total total.value = res.total
} finally { } finally {

View File

@ -117,8 +117,10 @@ const submitForm = async () => {
const resetForm = () => { const resetForm = () => {
formData.value = { formData.value = {
id: undefined, id: undefined,
code: '',
name: '', name: '',
picUrl: '', logo: '',
sort: 0,
status: CommonStatusEnum.ENABLE status: CommonStatusEnum.ENABLE
} }
formRef.value?.resetFields() formRef.value?.resetFields()

View File

@ -68,10 +68,8 @@ const submitForm = async () => {
// //
formLoading.value = true formLoading.value = true
try { try {
const data = cloneDeep(unref(formData)) const { payPrice: _payPrice, newPayPrice: _newPayPrice, ...data } = cloneDeep(unref(formData))
data.adjustPrice = convertToInteger(data.adjustPrice) data.adjustPrice = convertToInteger(data.adjustPrice)
delete data.payPrice
delete data.newPayPrice
await TradeOrderApi.updateOrderPrice(data) await TradeOrderApi.updateOrderPrice(data)
message.success(t('common.updateSuccess')) message.success(t('common.updateSuccess'))
dialogVisible.value = false dialogVisible.value = false

View File

@ -213,14 +213,12 @@ const getList = async () => {
try { try {
const data = cloneDeep(queryParams.value) const data = cloneDeep(queryParams.value)
// //
if (data.status === '0') { const queryData = data.status === '0' ? (({ status: _status, ...rest }) => rest)(data) : data
delete data.status
}
// //
if (props.userId) { if (props.userId) {
data.userId = props.userId as any queryData.userId = props.userId as any
} }
const res = await AfterSaleApi.getAfterSalePage(data) const res = await AfterSaleApi.getAfterSalePage(queryData)
list.value = res.list as AfterSaleApi.TradeAfterSaleVO[] list.value = res.list as AfterSaleApi.TradeAfterSaleVO[]
total.value = res.total total.value = res.total
} finally { } finally {

View File

@ -191,6 +191,7 @@
import { CommonStatusEnum } from '@/utils/constants' import { CommonStatusEnum } from '@/utils/constants'
import { DICT_TYPE, getDictOptions } from '@/utils/dict' import { DICT_TYPE, getDictOptions } from '@/utils/dict'
import * as ChannelApi from '@/api/pay/channel' import * as ChannelApi from '@/api/pay/channel'
import type { UploadRequestHandler, UploadRequestOptions } from 'element-plus'
defineOptions({ name: 'AlipayChannelForm' }) defineOptions({ name: 'AlipayChannelForm' })
@ -312,7 +313,7 @@ const resetForm = (appId, code) => {
formRef.value?.resetFields() formRef.value?.resetFields()
} }
const fileBeforeUpload = (file) => { const fileBeforeUpload = (file: File) => {
let format = '.' + file.name.split('.')[1] let format = '.' + file.name.split('.')[1]
if (format !== fileAccept) { if (format !== fileAccept) {
message.error(`请上传指定格式"${fileAccept}"文件`) message.error(`请上传指定格式"${fileAccept}"文件`)
@ -325,27 +326,36 @@ const fileBeforeUpload = (file) => {
return isRightSize return isRightSize
} }
const appCertUpload = (event) => { const readCertFile = (
const readFile = new FileReader() event: UploadRequestOptions,
readFile.onload = (e: any) => { setContent: (content: string) => void
formData.value.config.appCertContent = e.target.result ): Promise<void> => {
} return new Promise((resolve, reject) => {
readFile.readAsText(event.file) const readFile = new FileReader()
readFile.onload = (e) => {
setContent(String(e.target?.result || ''))
resolve()
}
readFile.onerror = () => reject(readFile.error)
readFile.readAsText(event.file)
})
} }
const alipayPublicCertUpload = (event) => { const appCertUpload: UploadRequestHandler = (event) => {
const readFile = new FileReader() return readCertFile(event, (content) => {
readFile.onload = (e: any) => { formData.value.config.appCertContent = content
formData.value.config.alipayPublicCertContent = e.target.result })
}
readFile.readAsText(event.file)
} }
const rootCertUpload = (event) => { const alipayPublicCertUpload: UploadRequestHandler = (event) => {
const readFile = new FileReader() return readCertFile(event, (content) => {
readFile.onload = (e: any) => { formData.value.config.alipayPublicCertContent = content
formData.value.config.rootCertContent = e.target.result })
} }
readFile.readAsText(event.file)
const rootCertUpload: UploadRequestHandler = (event) => {
return readCertFile(event, (content) => {
formData.value.config.rootCertContent = content
})
} }
</script> </script>

View File

@ -25,19 +25,19 @@
<div v-if="detailData.toMails && detailData.toMails.length > 0"> <div v-if="detailData.toMails && detailData.toMails.length > 0">
收件 收件
<span v-for="(mail, index) in detailData.toMails" :key="mail"> <span v-for="(mail, index) in detailData.toMails" :key="mail">
{{ mail }}<span v-if="index < detailData.toMails.length - 1"></span> {{ mail }}<span v-if="Number(index) < detailData.toMails.length - 1"></span>
</span> </span>
</div> </div>
<div v-if="detailData.ccMails && detailData.ccMails.length > 0"> <div v-if="detailData.ccMails && detailData.ccMails.length > 0">
抄送 抄送
<span v-for="(mail, index) in detailData.ccMails" :key="mail"> <span v-for="(mail, index) in detailData.ccMails" :key="mail">
{{ mail }}<span v-if="index < detailData.ccMails.length - 1"></span> {{ mail }}<span v-if="Number(index) < detailData.ccMails.length - 1"></span>
</span> </span>
</div> </div>
<div v-if="detailData.bccMails && detailData.bccMails.length > 0"> <div v-if="detailData.bccMails && detailData.bccMails.length > 0">
密送 密送
<span v-for="(mail, index) in detailData.bccMails" :key="mail"> <span v-for="(mail, index) in detailData.bccMails" :key="mail">
{{ mail }}<span v-if="index < detailData.bccMails.length - 1"></span> {{ mail }}<span v-if="Number(index) < detailData.bccMails.length - 1"></span>
</span> </span>
</div> </div>
</div> </div>

View File

@ -134,19 +134,19 @@
<div v-if="scope.row.toMails && scope.row.toMails.length > 0"> <div v-if="scope.row.toMails && scope.row.toMails.length > 0">
收件 收件
<span v-for="(mail, index) in scope.row.toMails" :key="mail"> <span v-for="(mail, index) in scope.row.toMails" :key="mail">
{{ mail }}<span v-if="index < scope.row.toMails.length - 1"></span> {{ mail }}<span v-if="Number(index) < scope.row.toMails.length - 1"></span>
</span> </span>
</div> </div>
<div v-if="scope.row.ccMails && scope.row.ccMails.length > 0"> <div v-if="scope.row.ccMails && scope.row.ccMails.length > 0">
抄送 抄送
<span v-for="(mail, index) in scope.row.ccMails" :key="mail"> <span v-for="(mail, index) in scope.row.ccMails" :key="mail">
{{ mail }}<span v-if="index < scope.row.ccMails.length - 1"></span> {{ mail }}<span v-if="Number(index) < scope.row.ccMails.length - 1"></span>
</span> </span>
</div> </div>
<div v-if="scope.row.bccMails && scope.row.bccMails.length > 0"> <div v-if="scope.row.bccMails && scope.row.bccMails.length > 0">
密送 密送
<span v-for="(mail, index) in scope.row.bccMails" :key="mail"> <span v-for="(mail, index) in scope.row.bccMails" :key="mail">
{{ mail }}<span v-if="index < scope.row.bccMails.length - 1"></span> {{ mail }}<span v-if="Number(index) < scope.row.bccMails.length - 1"></span>
</span> </span>
</div> </div>
</div> </div>