fix(vben): 修复 antdv-next 与 ele 端差异问题
- 修复 pay 收银台二维码展示:ele 使用 useQRCode 渲染协议串二维码,并补齐两端 QR 弹窗打开逻辑 - 修复 ele 端 mp 消息语音、视频播放器组件对调问题 - 修复 ele 端 ERP 库存单据商品、仓库下拉选项不渲染问题 - 修复 ele 端系统菜单组件路径搜索过滤逻辑 - 修复 ele 端 IM 表情包抽屉打开后不加载表情列表问题 - 修复 ele 端文件配置 loading 关闭路径,避免成功或异常后持续转圈 - 修复 ele 端客户公海、合同配置等 CRM 表单文案不可见问题,并保持两端数字校验一致 - 修复 BPM、商城、字典等页面的组件适配和条件判断差异 - 启用 web-antdv-next typecheck 脚本,保持与 web-ele 一致
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
"build:analyze": "pnpm vite build --mode analyze",
|
||||
"dev": "pnpm vite --mode development",
|
||||
"preview": "vite preview",
|
||||
"#typecheck": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vue-tsc --noEmit --skipLibCheck --incremental --tsBuildInfoFile node_modules/.cache/vue-tsc/tsconfig.tsbuildinfo"
|
||||
"typecheck": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vue-tsc --noEmit --skipLibCheck --incremental --tsBuildInfoFile node_modules/.cache/vue-tsc/tsconfig.tsbuildinfo"
|
||||
},
|
||||
"imports": {
|
||||
"#/*": "./src/*"
|
||||
|
||||
@@ -258,14 +258,14 @@ function updateFormFieldKey(
|
||||
) {
|
||||
if (!formSetting?.updateFormFields || !newKey) return;
|
||||
const value = formSetting.updateFormFields[oldKey];
|
||||
delete formSetting.updateFormFields.oldKey;
|
||||
delete formSetting.updateFormFields[oldKey];
|
||||
formSetting.updateFormFields[String(newKey)] = value;
|
||||
}
|
||||
|
||||
/** 删除修改字段设置项 */
|
||||
function deleteFormFieldSetting(formSetting: FormTriggerSetting, key: string) {
|
||||
if (!formSetting?.updateFormFields) return;
|
||||
delete formSetting.updateFormFields.key;
|
||||
delete formSetting.updateFormFields[key];
|
||||
}
|
||||
|
||||
/** 保存配置 */
|
||||
|
||||
@@ -135,6 +135,7 @@ function openStartDeptSelect() {
|
||||
|
||||
/** 处理部门选择确认 */
|
||||
function handleDeptSelectConfirm(depts: SystemDeptApi.Dept[]) {
|
||||
selectedStartDepts.value = depts;
|
||||
modelData.value = {
|
||||
...modelData.value,
|
||||
startDeptIds: depts.map((d) => d.id),
|
||||
|
||||
@@ -8,13 +8,14 @@ import { useRoute, useRouter } from 'vue-router';
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
import { useTabs } from '@vben/hooks';
|
||||
|
||||
import { Button, Card, TabPane, Tabs } from 'antdv-next';
|
||||
import { Card, TabPane, Tabs } from 'antdv-next';
|
||||
|
||||
import { getBusiness } from '#/api/crm/business';
|
||||
import { getOperateLogPage } from '#/api/crm/operateLog';
|
||||
import { BizTypeEnum } from '#/api/crm/permission';
|
||||
import { useDescription } from '#/components/description';
|
||||
import { OperateLog } from '#/components/operate-log';
|
||||
import { ACTION_ICON, TableAction } from '#/components/table-action';
|
||||
import { $t } from '#/locales';
|
||||
import { ContactDetailsList } from '#/views/crm/contact/components';
|
||||
import { ContractDetailsList } from '#/views/crm/contract/components';
|
||||
@@ -108,27 +109,36 @@ onMounted(() => {
|
||||
<TransferModal @success="getBusinessDetail" />
|
||||
<UpStatusModal @success="getBusinessDetail" />
|
||||
<template #extra>
|
||||
<div class="flex items-center gap-2">
|
||||
<Button
|
||||
v-if="permissionListRef?.validateWrite"
|
||||
type="primary"
|
||||
@click="handleEdit"
|
||||
>
|
||||
{{ $t('ui.actionTitle.edit') }}
|
||||
</Button>
|
||||
<Button
|
||||
v-if="permissionListRef?.validateWrite"
|
||||
@click="handleUpdateStatus"
|
||||
>
|
||||
变更商机状态
|
||||
</Button>
|
||||
<Button
|
||||
v-if="permissionListRef?.validateOwnerUser"
|
||||
@click="handleTransfer"
|
||||
>
|
||||
转移
|
||||
</Button>
|
||||
</div>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
label: '返回',
|
||||
type: 'default',
|
||||
icon: 'lucide:arrow-left',
|
||||
onClick: handleBack,
|
||||
},
|
||||
{
|
||||
label: $t('ui.actionTitle.edit'),
|
||||
type: 'primary',
|
||||
icon: ACTION_ICON.EDIT,
|
||||
auth: ['crm:business:update'],
|
||||
ifShow: permissionListRef?.validateWrite,
|
||||
onClick: handleEdit,
|
||||
},
|
||||
{
|
||||
label: '变更商机状态',
|
||||
type: 'primary',
|
||||
ifShow: permissionListRef?.validateWrite,
|
||||
onClick: handleUpdateStatus,
|
||||
},
|
||||
{
|
||||
label: '转移',
|
||||
type: 'primary',
|
||||
ifShow: permissionListRef?.validateOwnerUser,
|
||||
onClick: handleTransfer,
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
<Card class="min-h-[10%]">
|
||||
<Descriptions :data="business" />
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
|
||||
import { z } from '#/adapter/form';
|
||||
|
||||
export const schema: VbenFormSchema[] = [
|
||||
{
|
||||
component: 'RadioGroup',
|
||||
@@ -14,17 +16,17 @@ export const schema: VbenFormSchema[] = [
|
||||
defaultValue: true,
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
component: 'Input',
|
||||
fieldName: 'notifyDays',
|
||||
componentProps: {
|
||||
placeholder: '请输入天数',
|
||||
class: '!w-full',
|
||||
min: 0,
|
||||
precision: 0,
|
||||
},
|
||||
renderComponentContent: () => ({
|
||||
addonBefore: () => '提前',
|
||||
addonAfter: () => '天提醒',
|
||||
}),
|
||||
rules: z.coerce.number().int().min(0, '天数不能小于 0'),
|
||||
dependencies: {
|
||||
triggerFields: ['notifyEnabled'],
|
||||
show: (values) => values.notifyEnabled,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
|
||||
import { z } from '#/adapter/form';
|
||||
|
||||
export const schema: VbenFormSchema[] = [
|
||||
{
|
||||
component: 'RadioGroup',
|
||||
@@ -13,33 +15,33 @@ export const schema: VbenFormSchema[] = [
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
component: 'Input',
|
||||
fieldName: 'contactExpireDays',
|
||||
componentProps: {
|
||||
placeholder: '请输入天数',
|
||||
class: '!w-full',
|
||||
min: 0,
|
||||
precision: 0,
|
||||
},
|
||||
renderComponentContent: () => ({
|
||||
addonAfter: () => '天不跟进或',
|
||||
}),
|
||||
rules: z.coerce.number().int().min(0, '天数不能小于 0'),
|
||||
dependencies: {
|
||||
triggerFields: ['enabled'],
|
||||
show: (value) => value.enabled,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
component: 'Input',
|
||||
fieldName: 'dealExpireDays',
|
||||
renderComponentContent: () => ({
|
||||
addonBefore: () => '或',
|
||||
addonAfter: () => '天未成交',
|
||||
}),
|
||||
componentProps: {
|
||||
placeholder: '请输入天数',
|
||||
class: '!w-full',
|
||||
min: 0,
|
||||
precision: 0,
|
||||
},
|
||||
rules: z.coerce.number().int().min(0, '天数不能小于 0'),
|
||||
dependencies: {
|
||||
triggerFields: ['enabled'],
|
||||
show: (value) => value.enabled,
|
||||
@@ -62,17 +64,17 @@ export const schema: VbenFormSchema[] = [
|
||||
defaultValue: false,
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
component: 'Input',
|
||||
fieldName: 'notifyDays',
|
||||
componentProps: {
|
||||
placeholder: '请输入天数',
|
||||
class: '!w-full',
|
||||
min: 0,
|
||||
precision: 0,
|
||||
},
|
||||
renderComponentContent: () => ({
|
||||
addonBefore: () => '提前',
|
||||
addonAfter: () => '天提醒',
|
||||
}),
|
||||
rules: z.coerce.number().int().min(0, '天数不能小于 0'),
|
||||
dependencies: {
|
||||
triggerFields: ['notifyEnabled'],
|
||||
show: (value) => value.enabled && value.notifyEnabled,
|
||||
|
||||
@@ -99,7 +99,7 @@ function calculateWidth() {
|
||||
:class="[
|
||||
{
|
||||
'w-full': property.layoutType !== 'oneColSmallImg',
|
||||
'w-[calc(100vh-140px-16px)]':
|
||||
'w-[calc(100%-140px-16px)]':
|
||||
property.layoutType === 'oneColSmallImg',
|
||||
},
|
||||
]"
|
||||
|
||||
@@ -44,6 +44,9 @@ defineProps<{
|
||||
<div v-else-if="item.event === 'location_select'">
|
||||
<Tag>选择地理位置</Tag>
|
||||
</div>
|
||||
<div v-else-if="item.event === 'SCAN'">
|
||||
<Tag>扫码</Tag>
|
||||
</div>
|
||||
<div v-else>
|
||||
<Tag color="error">未知事件类型</Tag>
|
||||
</div>
|
||||
|
||||
@@ -213,6 +213,7 @@ function displayQrCode(channelCode: string, data: any) {
|
||||
url: data.displayContent,
|
||||
visible: true,
|
||||
};
|
||||
modalApi.open();
|
||||
}
|
||||
|
||||
/** 提交支付后(App) */
|
||||
|
||||
@@ -126,51 +126,56 @@ const resetTaskForm = () => {
|
||||
(ex: any) => ex.$type === `${prefix}:CandidateParam`,
|
||||
)?.value;
|
||||
if (candidateParamStr && candidateParamStr.length > 0) {
|
||||
if (userTaskForm.value.candidateStrategy === CandidateStrategy.EXPRESSION) {
|
||||
// 特殊:流程表达式,只有一个 input 输入框
|
||||
// @ts-expect-error: expression strategy stores a scalar in an array-shaped field
|
||||
userTaskForm.value.candidateParam = [candidateParamStr];
|
||||
} else if (
|
||||
userTaskForm.value.candidateStrategy ===
|
||||
CandidateStrategy.MULTI_LEVEL_DEPT_LEADER
|
||||
) {
|
||||
// 特殊:多级不部门负责人,需要通过'|'分割
|
||||
userTaskForm.value.candidateParam = candidateParamStr
|
||||
.split('|')[0]
|
||||
.split(',')
|
||||
.map((item: any) => {
|
||||
// 如果数字超出了最大安全整数范围,则将其作为字符串处理
|
||||
const num = Number(item);
|
||||
return num > Number.MAX_SAFE_INTEGER || num < -Number.MAX_SAFE_INTEGER
|
||||
? item
|
||||
: num;
|
||||
});
|
||||
deptLevel.value = +candidateParamStr.split('|')[1];
|
||||
} else if (
|
||||
userTaskForm.value.candidateStrategy ===
|
||||
CandidateStrategy.START_USER_DEPT_LEADER ||
|
||||
userTaskForm.value.candidateStrategy ===
|
||||
CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER
|
||||
) {
|
||||
// @ts-expect-error: dynamic candidate param shape varies by strategy
|
||||
userTaskForm.value.candidateParam = +candidateParamStr;
|
||||
deptLevel.value = +candidateParamStr;
|
||||
} else if (
|
||||
userTaskForm.value.candidateStrategy ===
|
||||
CandidateStrategy.FORM_DEPT_LEADER
|
||||
) {
|
||||
userTaskForm.value.candidateParam = candidateParamStr.split('|')[0];
|
||||
deptLevel.value = +candidateParamStr.split('|')[1];
|
||||
} else {
|
||||
userTaskForm.value.candidateParam = candidateParamStr
|
||||
.split(',')
|
||||
.map((item: any) => {
|
||||
// 如果数字超出了最大安全整数范围,则将其作为字符串处理
|
||||
const num = Number(item);
|
||||
return num > Number.MAX_SAFE_INTEGER || num < -Number.MAX_SAFE_INTEGER
|
||||
? item
|
||||
: num;
|
||||
});
|
||||
const candidateStrategy = userTaskForm.value.candidateStrategy as
|
||||
| CandidateStrategy
|
||||
| undefined;
|
||||
switch (candidateStrategy) {
|
||||
case CandidateStrategy.EXPRESSION: {
|
||||
// 特殊:流程表达式,只有一个 input 输入框
|
||||
// @ts-expect-error: expression strategy stores a scalar in an array-shaped field
|
||||
userTaskForm.value.candidateParam = [candidateParamStr];
|
||||
break;
|
||||
}
|
||||
case CandidateStrategy.FORM_DEPT_LEADER: {
|
||||
userTaskForm.value.candidateParam = candidateParamStr.split('|')[0];
|
||||
deptLevel.value = +candidateParamStr.split('|')[1];
|
||||
break;
|
||||
}
|
||||
case CandidateStrategy.MULTI_LEVEL_DEPT_LEADER: {
|
||||
// 特殊:多级不部门负责人,需要通过'|'分割
|
||||
userTaskForm.value.candidateParam = candidateParamStr
|
||||
.split('|')[0]
|
||||
.split(',')
|
||||
.map((item: any) => {
|
||||
// 如果数字超出了最大安全整数范围,则将其作为字符串处理
|
||||
const num = Number(item);
|
||||
return num > Number.MAX_SAFE_INTEGER ||
|
||||
num < -Number.MAX_SAFE_INTEGER
|
||||
? item
|
||||
: num;
|
||||
});
|
||||
deptLevel.value = +candidateParamStr.split('|')[1];
|
||||
break;
|
||||
}
|
||||
case CandidateStrategy.START_USER_DEPT_LEADER:
|
||||
case CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER: {
|
||||
// @ts-expect-error: dynamic candidate param shape varies by strategy
|
||||
userTaskForm.value.candidateParam = +candidateParamStr;
|
||||
deptLevel.value = +candidateParamStr;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
userTaskForm.value.candidateParam = candidateParamStr
|
||||
.split(',')
|
||||
.map((item: any) => {
|
||||
// 如果数字超出了最大安全整数范围,则将其作为字符串处理
|
||||
const num = Number(item);
|
||||
return num > Number.MAX_SAFE_INTEGER ||
|
||||
num < -Number.MAX_SAFE_INTEGER
|
||||
? item
|
||||
: num;
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
userTaskForm.value.candidateParam = [];
|
||||
@@ -402,7 +407,6 @@ onBeforeUnmount(() => {
|
||||
:props="defaultProps"
|
||||
placeholder="加载中,请稍后"
|
||||
multiple
|
||||
check-strictly
|
||||
show-checkbox
|
||||
@change="updateElementTask"
|
||||
/>
|
||||
|
||||
@@ -9,6 +9,22 @@ import { useVbenDrawer } from '@vben/common-ui';
|
||||
import { BpmNodeTypeEnum } from '@vben/constants';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import {
|
||||
ElButton,
|
||||
ElDatePicker,
|
||||
ElDivider,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElInput,
|
||||
ElInputNumber,
|
||||
ElOption,
|
||||
ElRadio,
|
||||
ElRadioButton,
|
||||
ElRadioGroup,
|
||||
ElSelect,
|
||||
ElSwitch,
|
||||
} from 'element-plus';
|
||||
|
||||
import { getForm } from '#/api/bpm/form';
|
||||
import { getModelList } from '#/api/bpm/model';
|
||||
|
||||
@@ -442,7 +458,7 @@ onMounted(async () => {
|
||||
>
|
||||
<div class="mr-2 mt-1">
|
||||
<ElFormItem
|
||||
:prop="['inVariables', index, 'source']"
|
||||
:prop="`inVariables.${index}.source`"
|
||||
:rules="{
|
||||
required: true,
|
||||
message: '变量不能为空',
|
||||
@@ -461,7 +477,7 @@ onMounted(async () => {
|
||||
</div>
|
||||
<div class="mr-2 mt-1">
|
||||
<ElFormItem
|
||||
:prop="['inVariables', index, 'target']"
|
||||
:prop="`inVariables.${index}.target`"
|
||||
:rules="{
|
||||
required: true,
|
||||
message: '变量不能为空',
|
||||
@@ -510,7 +526,7 @@ onMounted(async () => {
|
||||
>
|
||||
<div class="mr-2 mt-1">
|
||||
<ElFormItem
|
||||
:prop="['outVariables', index, 'source']"
|
||||
:prop="`outVariables.${index}.source`"
|
||||
:rules="{
|
||||
required: true,
|
||||
message: '变量不能为空',
|
||||
@@ -529,7 +545,7 @@ onMounted(async () => {
|
||||
</div>
|
||||
<div class="mr-2 mt-1">
|
||||
<ElFormItem
|
||||
:prop="['outVariables', index, 'target']"
|
||||
:prop="`outVariables.${index}.target`"
|
||||
:rules="{
|
||||
required: true,
|
||||
message: '变量不能为空',
|
||||
|
||||
@@ -258,14 +258,14 @@ function updateFormFieldKey(
|
||||
) {
|
||||
if (!formSetting?.updateFormFields || !newKey) return;
|
||||
const value = formSetting.updateFormFields[oldKey];
|
||||
delete formSetting.updateFormFields.oldkey;
|
||||
delete formSetting.updateFormFields[oldKey];
|
||||
formSetting.updateFormFields[String(newKey)] = value;
|
||||
}
|
||||
|
||||
/** 删除修改字段设置项 */
|
||||
function deleteFormFieldSetting(formSetting: FormTriggerSetting, key: string) {
|
||||
if (!formSetting?.updateFormFields) return;
|
||||
delete formSetting.updateFormFields.key;
|
||||
delete formSetting.updateFormFields[key];
|
||||
}
|
||||
|
||||
/** 保存配置 */
|
||||
|
||||
@@ -103,7 +103,7 @@ onBeforeUnmount(() => {
|
||||
<div class="mb-3">
|
||||
<ElAlert
|
||||
title="输入 @ 可选择插入流程选项和表单选项"
|
||||
type="primary"
|
||||
type="info"
|
||||
show-icon
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useVbenModal } from '@vben/common-ui';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
import { base64ToFile } from '@vben/utils';
|
||||
|
||||
import { ElButton, ElTooltip } from 'element-plus';
|
||||
import Vue3Signature from 'vue3-signature';
|
||||
|
||||
import { uploadFile } from '#/api/infra/file';
|
||||
|
||||
@@ -9,6 +9,7 @@ import { DICT_TYPE } from '@vben/constants';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import FormCreate from '@form-create/element-ui';
|
||||
import { ElButton } from 'element-plus';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getTaskListByProcessInstanceId } from '#/api/bpm/task';
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
erpPriceMultiply,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { ElInput, ElInputNumber, ElSelect } from 'element-plus';
|
||||
import { ElInput, ElInputNumber, ElOption, ElSelect } from 'element-plus';
|
||||
|
||||
import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getProductSimpleList } from '#/api/erp/product/product';
|
||||
@@ -219,26 +219,36 @@ onMounted(async () => {
|
||||
<template #warehouseId="{ row }">
|
||||
<ElSelect
|
||||
v-model="row.warehouseId"
|
||||
:options="warehouseOptions"
|
||||
:props="{ label: 'name', value: 'id' }"
|
||||
class="w-full"
|
||||
placeholder="请选择仓库"
|
||||
filterable
|
||||
:disabled="disabled"
|
||||
@change="handleWarehouseChange($event, row)"
|
||||
/>
|
||||
>
|
||||
<ElOption
|
||||
v-for="warehouse in warehouseOptions"
|
||||
:key="warehouse.id"
|
||||
:label="warehouse.name"
|
||||
:value="warehouse.id!"
|
||||
/>
|
||||
</ElSelect>
|
||||
</template>
|
||||
<template #productId="{ row }">
|
||||
<ElSelect
|
||||
v-model="row.productId"
|
||||
:options="productOptions"
|
||||
:props="{ label: 'name', value: 'id' }"
|
||||
class="w-full"
|
||||
placeholder="请选择产品"
|
||||
filterable
|
||||
:disabled="disabled"
|
||||
@change="handleProductChange($event, row)"
|
||||
/>
|
||||
>
|
||||
<ElOption
|
||||
v-for="product in productOptions"
|
||||
:key="product.id"
|
||||
:label="product.name"
|
||||
:value="product.id!"
|
||||
/>
|
||||
</ElSelect>
|
||||
</template>
|
||||
<template #actualCount="{ row }">
|
||||
<ElInputNumber
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
erpPriceMultiply,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { ElInput, ElInputNumber, ElSelect } from 'element-plus';
|
||||
import { ElInput, ElInputNumber, ElOption, ElSelect } from 'element-plus';
|
||||
|
||||
import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getProductSimpleList } from '#/api/erp/product/product';
|
||||
@@ -208,26 +208,36 @@ onMounted(async () => {
|
||||
<template #warehouseId="{ row }">
|
||||
<ElSelect
|
||||
v-model="row.warehouseId"
|
||||
:options="warehouseOptions"
|
||||
:props="{ label: 'name', value: 'id' }"
|
||||
class="w-full"
|
||||
placeholder="请选择仓库"
|
||||
filterable
|
||||
:disabled="disabled"
|
||||
@change="handleWarehouseChange($event, row)"
|
||||
/>
|
||||
>
|
||||
<ElOption
|
||||
v-for="warehouse in warehouseOptions"
|
||||
:key="warehouse.id"
|
||||
:label="warehouse.name"
|
||||
:value="warehouse.id!"
|
||||
/>
|
||||
</ElSelect>
|
||||
</template>
|
||||
<template #productId="{ row }">
|
||||
<ElSelect
|
||||
v-model="row.productId"
|
||||
:options="productOptions"
|
||||
:props="{ label: 'name', value: 'id' }"
|
||||
class="w-full"
|
||||
placeholder="请选择产品"
|
||||
filterable
|
||||
:disabled="disabled"
|
||||
@change="handleProductChange($event, row)"
|
||||
/>
|
||||
>
|
||||
<ElOption
|
||||
v-for="product in productOptions"
|
||||
:key="product.id"
|
||||
:label="product.name"
|
||||
:value="product.id!"
|
||||
/>
|
||||
</ElSelect>
|
||||
</template>
|
||||
<template #count="{ row }">
|
||||
<ElInputNumber
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
erpPriceMultiply,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { ElInput, ElInputNumber, ElSelect } from 'element-plus';
|
||||
import { ElInput, ElInputNumber, ElOption, ElSelect } from 'element-plus';
|
||||
|
||||
import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getProductSimpleList } from '#/api/erp/product/product';
|
||||
@@ -216,38 +216,53 @@ onMounted(async () => {
|
||||
<template #fromWarehouseId="{ row }">
|
||||
<ElSelect
|
||||
v-model="row.fromWarehouseId"
|
||||
:options="warehouseOptions"
|
||||
:props="{ label: 'name', value: 'id' }"
|
||||
class="w-full"
|
||||
placeholder="请选择调出仓库"
|
||||
filterable
|
||||
:disabled="disabled"
|
||||
@change="handleFromWarehouseChange($event, row)"
|
||||
/>
|
||||
>
|
||||
<ElOption
|
||||
v-for="warehouse in warehouseOptions"
|
||||
:key="warehouse.id"
|
||||
:label="warehouse.name"
|
||||
:value="warehouse.id!"
|
||||
/>
|
||||
</ElSelect>
|
||||
</template>
|
||||
<template #toWarehouseId="{ row }">
|
||||
<ElSelect
|
||||
v-model="row.toWarehouseId"
|
||||
:options="warehouseOptions"
|
||||
:props="{ label: 'name', value: 'id' }"
|
||||
class="w-full"
|
||||
placeholder="请选择调入仓库"
|
||||
filterable
|
||||
:disabled="disabled"
|
||||
@change="handleToWarehouseChange($event, row)"
|
||||
/>
|
||||
>
|
||||
<ElOption
|
||||
v-for="warehouse in warehouseOptions"
|
||||
:key="warehouse.id"
|
||||
:label="warehouse.name"
|
||||
:value="warehouse.id!"
|
||||
/>
|
||||
</ElSelect>
|
||||
</template>
|
||||
<template #productId="{ row }">
|
||||
<ElSelect
|
||||
v-model="row.productId"
|
||||
:options="productOptions"
|
||||
:props="{ label: 'name', value: 'id' }"
|
||||
class="w-full"
|
||||
placeholder="请选择产品"
|
||||
filterable
|
||||
:disabled="disabled"
|
||||
@change="handleProductChange($event, row)"
|
||||
/>
|
||||
>
|
||||
<ElOption
|
||||
v-for="product in productOptions"
|
||||
:key="product.id"
|
||||
:label="product.name"
|
||||
:value="product.id!"
|
||||
/>
|
||||
</ElSelect>
|
||||
</template>
|
||||
<template #count="{ row }">
|
||||
<ElInputNumber
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
erpPriceMultiply,
|
||||
} from '@vben/utils';
|
||||
|
||||
import { ElInput, ElInputNumber, ElSelect } from 'element-plus';
|
||||
import { ElInput, ElInputNumber, ElOption, ElSelect } from 'element-plus';
|
||||
|
||||
import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getProductSimpleList } from '#/api/erp/product/product';
|
||||
@@ -206,26 +206,36 @@ onMounted(async () => {
|
||||
<template #warehouseId="{ row }">
|
||||
<ElSelect
|
||||
v-model="row.warehouseId"
|
||||
:options="warehouseOptions"
|
||||
:props="{ label: 'name', value: 'id' }"
|
||||
class="w-full"
|
||||
placeholder="请选择仓库"
|
||||
filterable
|
||||
:disabled="disabled"
|
||||
@change="handleWarehouseChange($event, row)"
|
||||
/>
|
||||
>
|
||||
<ElOption
|
||||
v-for="warehouse in warehouseOptions"
|
||||
:key="warehouse.id"
|
||||
:label="warehouse.name"
|
||||
:value="warehouse.id!"
|
||||
/>
|
||||
</ElSelect>
|
||||
</template>
|
||||
<template #productId="{ row }">
|
||||
<ElSelect
|
||||
v-model="row.productId"
|
||||
:options="productOptions"
|
||||
:props="{ label: 'name', value: 'id' }"
|
||||
class="w-full"
|
||||
placeholder="请选择产品"
|
||||
filterable
|
||||
:disabled="disabled"
|
||||
@change="handleProductChange($event, row)"
|
||||
/>
|
||||
>
|
||||
<ElOption
|
||||
v-for="product in productOptions"
|
||||
:key="product.id"
|
||||
:label="product.name"
|
||||
:value="product.id!"
|
||||
/>
|
||||
</ElSelect>
|
||||
</template>
|
||||
<template #count="{ row }">
|
||||
<ElInputNumber
|
||||
|
||||
@@ -150,7 +150,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||
:title="title"
|
||||
destroy-on-close
|
||||
width="65%"
|
||||
@after-open-change="handleOpenChange"
|
||||
@opened="handleOpenChange(true)"
|
||||
>
|
||||
<ItemFormModal @success="handleRefresh" />
|
||||
<Grid table-title="表情列表">
|
||||
|
||||
@@ -49,9 +49,9 @@ async function handleMaster(row: InfraFileConfigApi.FileConfig) {
|
||||
});
|
||||
try {
|
||||
await updateFileConfigMaster(row.id!);
|
||||
ElMessage.success($t('ui.actionMessage.operationSuccess'));
|
||||
ElMessage.success($t('ui.actionMessage.updateSuccess'));
|
||||
handleRefresh();
|
||||
} catch {
|
||||
} finally {
|
||||
loadingInstance.close();
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,6 @@ async function handleTest(row: InfraFileConfigApi.FileConfig) {
|
||||
});
|
||||
try {
|
||||
const response = await testFileConfig(row.id!);
|
||||
loadingInstance.close();
|
||||
// 确认是否访问该文件
|
||||
confirm({
|
||||
title: '测试上传成功',
|
||||
@@ -73,7 +72,7 @@ async function handleTest(row: InfraFileConfigApi.FileConfig) {
|
||||
}).then(() => {
|
||||
openWindow(response);
|
||||
});
|
||||
} catch {
|
||||
} finally {
|
||||
loadingInstance.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ onMounted(async () => {
|
||||
}"
|
||||
:multiple="multiple"
|
||||
:show-checkbox="multiple"
|
||||
check-strictly
|
||||
clearable
|
||||
default-expand-all
|
||||
class="w-full"
|
||||
placeholder="请选择商品分类"
|
||||
|
||||
@@ -15,12 +15,14 @@ import { floatToFixed2 } from '@vben/utils';
|
||||
|
||||
import { useVModel } from '@vueuse/core';
|
||||
import {
|
||||
ElButton,
|
||||
ElCard,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElRadioButton,
|
||||
ElRadioGroup,
|
||||
ElSlider,
|
||||
ElText,
|
||||
ElTooltip,
|
||||
} from 'element-plus';
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { IconifyIcon } from '@vben/icons';
|
||||
import { useVModel } from '@vueuse/core';
|
||||
import {
|
||||
ElCard,
|
||||
ElCheckbox,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElInput,
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElInput,
|
||||
ElRadio,
|
||||
ElRadioButton,
|
||||
ElRadioGroup,
|
||||
ElSlider,
|
||||
|
||||
@@ -10,6 +10,7 @@ import { cloneDeep, isEmpty, isString } from '@vben/utils';
|
||||
import { useQRCode } from '@vueuse/integrations/useQRCode';
|
||||
import {
|
||||
ElAside,
|
||||
ElButton,
|
||||
ElCard,
|
||||
ElContainer,
|
||||
ElHeader,
|
||||
|
||||
@@ -81,7 +81,10 @@ const handleDelete = function (index: number) {
|
||||
</div>
|
||||
</template>
|
||||
</VueDraggable>
|
||||
<ElTooltip :disabled="limit < 1" :content="`最多添加${limit}个`">
|
||||
<ElTooltip
|
||||
:disabled="limit >= Number.MAX_VALUE"
|
||||
:content="`最多添加${limit}个`"
|
||||
>
|
||||
<ElButton
|
||||
type="primary"
|
||||
plain
|
||||
|
||||
@@ -67,7 +67,7 @@ async function getPageDetail(id: any) {
|
||||
// 拼接手机预览链接
|
||||
const domain = import.meta.env.VITE_MALL_H5_DOMAIN;
|
||||
const accessStore = useAccessStore();
|
||||
previewUrl.value = `${domain}?templateId=${formData.value.id}&${accessStore.tenantId}`;
|
||||
previewUrl.value = `${domain}?templateId=${formData.value.id}&tenantId=${accessStore.tenantId}`;
|
||||
} finally {
|
||||
loadingInstance.close();
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ async function handleExport() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ElCard :bordered="false" shadow="never" class="h-full">
|
||||
<ElCard :border="false" shadow="never" class="h-full">
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-base font-medium">交易状况</span>
|
||||
|
||||
@@ -11,6 +11,7 @@ import { formatDate, isEmpty } from '@vben/utils';
|
||||
|
||||
import {
|
||||
ElAvatar,
|
||||
ElButton,
|
||||
ElDescriptions,
|
||||
ElDescriptionsItem,
|
||||
ElDivider,
|
||||
|
||||
@@ -11,6 +11,7 @@ import { formatDate, isEmpty } from '@vben/utils';
|
||||
|
||||
import {
|
||||
ElAvatar,
|
||||
ElButton,
|
||||
ElDescriptions,
|
||||
ElDescriptionsItem,
|
||||
ElDivider,
|
||||
|
||||
@@ -165,7 +165,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||
link: true,
|
||||
ifShow: () =>
|
||||
row.deliveryType === DeliveryTypeEnum.EXPRESS.type &&
|
||||
row.status === TradeOrderStatusEnum.UNDELIVERED.status,
|
||||
(row.status === TradeOrderStatusEnum.UNDELIVERED.status ||
|
||||
row.status === TradeOrderStatusEnum.DELIVERED.status),
|
||||
onClick: handleDelivery.bind(null, row),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -129,13 +129,13 @@ const [Modal, modalApi] = useVbenModal({
|
||||
v-model="subTabsName"
|
||||
class="mx-4 mt-4"
|
||||
>
|
||||
<ElTabPane name="machine" label="设备资源">
|
||||
<ElTabPane name="machine" label="设备资源" lazy>
|
||||
<MachineList :form-type="formType" :workstation-id="formData.id" />
|
||||
</ElTabPane>
|
||||
<ElTabPane name="tool" label="工装夹具">
|
||||
<ElTabPane name="tool" label="工装夹具" lazy>
|
||||
<ToolList :form-type="formType" :workstation-id="formData.id" />
|
||||
</ElTabPane>
|
||||
<ElTabPane name="worker" label="人力资源">
|
||||
<ElTabPane name="worker" label="人力资源" lazy>
|
||||
<WorkerList :form-type="formType" :workstation-id="formData.id" />
|
||||
</ElTabPane>
|
||||
</ElTabs>
|
||||
|
||||
@@ -30,7 +30,7 @@ withDefaults(
|
||||
<div v-else-if="item.type === MpMsgType.Text">{{ item.content }}</div>
|
||||
|
||||
<div v-else-if="item.type === MpMsgType.Voice">
|
||||
<WxVideoPlayer :url="item.mediaUrl" :content="item.recognition" />
|
||||
<WxVoicePlayer :url="item.mediaUrl" :content="item.recognition" />
|
||||
</div>
|
||||
|
||||
<div v-else-if="item.type === MpMsgType.Image">
|
||||
@@ -43,7 +43,7 @@ withDefaults(
|
||||
v-else-if="item.type === MpMsgType.Video || item.type === 'shortvideo'"
|
||||
class="text-center"
|
||||
>
|
||||
<WxVoicePlayer :url="item.mediaUrl" />
|
||||
<WxVideoPlayer :url="item.mediaUrl" />
|
||||
</div>
|
||||
|
||||
<div v-else-if="item.type === MpMsgType.Link" class="flex-1">
|
||||
|
||||
@@ -133,14 +133,30 @@ function selectMaterial(item: any) {
|
||||
</ElDialog>
|
||||
</ElCol>
|
||||
<ElCol :span="18">
|
||||
<ElInput v-model="reply.title" placeholder="请输入标题" />
|
||||
<ElInput
|
||||
:model-value="reply.title || undefined"
|
||||
placeholder="请输入标题"
|
||||
@update:model-value="(val) => (reply.title = val || null)"
|
||||
/>
|
||||
<div class="my-5"></div>
|
||||
<ElInput v-model="reply.description" placeholder="请输入描述" />
|
||||
<ElInput
|
||||
:model-value="reply.description || undefined"
|
||||
placeholder="请输入描述"
|
||||
@update:model-value="(val) => (reply.description = val || null)"
|
||||
/>
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
<div class="my-5"></div>
|
||||
<ElInput v-model="reply.musicUrl" placeholder="请输入音乐链接" />
|
||||
<ElInput
|
||||
:model-value="reply.musicUrl || undefined"
|
||||
placeholder="请输入音乐链接"
|
||||
@update:model-value="(val) => (reply.musicUrl = val || null)"
|
||||
/>
|
||||
<div class="my-5"></div>
|
||||
<ElInput v-model="reply.hqMusicUrl" placeholder="请输入高质量音乐链接" />
|
||||
<ElInput
|
||||
:model-value="reply.hqMusicUrl || undefined"
|
||||
placeholder="请输入高质量音乐链接"
|
||||
@update:model-value="(val) => (reply.hqMusicUrl = val || null)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -12,10 +12,10 @@ const emit = defineEmits<{
|
||||
}>();
|
||||
|
||||
const content = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val: null | string) => {
|
||||
emit('update:modelValue', val);
|
||||
emit('input', val);
|
||||
get: () => props.modelValue ?? '',
|
||||
set: (val: string) => {
|
||||
emit('update:modelValue', val || null);
|
||||
emit('input', val || null);
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -91,11 +91,17 @@ function selectMaterial(item: any) {
|
||||
<template>
|
||||
<div>
|
||||
<ElRow>
|
||||
<ElInput v-model="reply.title" class="mb-[2%]" placeholder="请输入标题" />
|
||||
<ElInput
|
||||
:model-value="reply.title || undefined"
|
||||
class="mb-[2%]"
|
||||
placeholder="请输入标题"
|
||||
@update:model-value="(val) => (reply.title = val || null)"
|
||||
/>
|
||||
<ElInput
|
||||
class="mb-[2%]"
|
||||
v-model="reply.description"
|
||||
:model-value="reply.description || undefined"
|
||||
placeholder="请输入描述"
|
||||
@update:model-value="(val) => (reply.description = val || null)"
|
||||
/>
|
||||
<ElRow class="w-full pt-[10px] text-center" justify="center">
|
||||
<VideoPlayer v-if="reply.url" :url="reply.url" />
|
||||
|
||||
@@ -113,7 +113,7 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ElTabs type="border-card" v-model="reply.type" @tab-change="clear">
|
||||
<ElTabs type="border-card" v-model="currentTab">
|
||||
<!-- 类型 1:文本 -->
|
||||
<ElTabPane :name="ReplyType.Text">
|
||||
<template #label>
|
||||
|
||||
@@ -13,11 +13,12 @@ import {
|
||||
import { useTabs } from '@vben/hooks';
|
||||
import { fenToYuan, formatDate } from '@vben/utils';
|
||||
|
||||
import { useQRCode } from '@vueuse/integrations/useQRCode';
|
||||
import {
|
||||
ElButton,
|
||||
ElCard,
|
||||
ElDescriptions,
|
||||
ElImage,
|
||||
ElDescriptionsItem,
|
||||
ElInput,
|
||||
ElMessage,
|
||||
} from 'element-plus';
|
||||
@@ -48,6 +49,10 @@ const qrCode = ref({
|
||||
url: '',
|
||||
visible: false,
|
||||
});
|
||||
const qrCodeImage = useQRCode(() => qrCode.value.url, {
|
||||
errorCorrectionLevel: 'H',
|
||||
margin: 4,
|
||||
});
|
||||
|
||||
/** 展示形式:条形码 */
|
||||
const barCode = ref({
|
||||
@@ -212,6 +217,7 @@ function displayQrCode(channelCode: string, data: any) {
|
||||
url: data.displayContent,
|
||||
visible: true,
|
||||
};
|
||||
modalApi.open();
|
||||
}
|
||||
|
||||
/** 提交支付后(App) */
|
||||
@@ -307,24 +313,24 @@ onBeforeUnmount(() => {
|
||||
<Page auto-content-height>
|
||||
<ElCard class="mt-4">
|
||||
<ElDescriptions :column="3" :title="payOrder?.subject ?? '商品详情'">
|
||||
<ElDescriptions.Item label="支付单号">
|
||||
<ElDescriptionsItem label="支付单号">
|
||||
{{ payOrder?.id }}
|
||||
</ElDescriptions.Item>
|
||||
<ElDescriptions.Item label="商品标题">
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="商品标题">
|
||||
{{ payOrder?.subject }}
|
||||
</ElDescriptions.Item>
|
||||
<ElDescriptions.Item label="商品内容">
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="商品内容">
|
||||
{{ payOrder?.body }}
|
||||
</ElDescriptions.Item>
|
||||
<ElDescriptions.Item label="支付金额">
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="支付金额">
|
||||
{{ `¥${fenToYuan(payOrder?.price || 0)}` }}
|
||||
</ElDescriptions.Item>
|
||||
<ElDescriptions.Item label="创建时间">
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="创建时间">
|
||||
{{ formatDate(payOrder?.createTime) }}
|
||||
</ElDescriptions.Item>
|
||||
<ElDescriptions.Item label="过期时间">
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="过期时间">
|
||||
{{ formatDate(payOrder?.expireTime) }}
|
||||
</ElDescriptions.Item>
|
||||
</ElDescriptionsItem>
|
||||
</ElDescriptions>
|
||||
</ElCard>
|
||||
<ElCard title="选择支付宝支付" class="mt-4">
|
||||
@@ -373,10 +379,15 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
</ElCard>
|
||||
<Modal class="w-2/5" :title="title">
|
||||
<ElImage v-if="qrCode.visible" :src="qrCode.url" />
|
||||
<img
|
||||
v-if="qrCode.visible"
|
||||
:src="qrCodeImage"
|
||||
alt="支付二维码"
|
||||
class="max-w-full"
|
||||
/>
|
||||
<ElInput
|
||||
v-if="barCode.visible"
|
||||
v-model:value="barCode.value"
|
||||
v-model="barCode.value"
|
||||
placeholder="请输入条形码"
|
||||
required
|
||||
/>
|
||||
|
||||
@@ -181,6 +181,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||
auth: ['system:dept:delete'],
|
||||
disabled: row.children && row.children.length > 0,
|
||||
popConfirm: {
|
||||
disabled: row.children && row.children.length > 0,
|
||||
title: $t('ui.actionMessage.deleteConfirm', [row.name]),
|
||||
confirm: handleDelete.bind(null, row),
|
||||
},
|
||||
|
||||
@@ -325,11 +325,13 @@ export function useDataGridColumns(): VxeTableGridOptions['columns'] {
|
||||
field: 'colorType',
|
||||
title: '颜色类型',
|
||||
minWidth: 120,
|
||||
slots: { default: 'colorType' },
|
||||
},
|
||||
{
|
||||
field: 'cssClass',
|
||||
title: 'CSS Class',
|
||||
minWidth: 120,
|
||||
slots: { default: 'cssClass' },
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ref, watch } from 'vue';
|
||||
import { confirm, useVbenModal } from '@vben/common-ui';
|
||||
import { downloadFileFromBlobPart, isEmpty } from '@vben/utils';
|
||||
|
||||
import { ElLoading, ElMessage } from 'element-plus';
|
||||
import { ElLoading, ElMessage, ElTag } from 'element-plus';
|
||||
|
||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import {
|
||||
@@ -172,6 +172,12 @@ watch(
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
<template #colorType="{ row }">
|
||||
<ElTag :color="row.colorType">{{ row.colorType }}</ElTag>
|
||||
</template>
|
||||
<template #cssClass="{ row }">
|
||||
<ElTag :color="row.cssClass">{{ row.cssClass }}</ElTag>
|
||||
</template>
|
||||
<template #actions="{ row }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
|
||||
@@ -174,7 +174,7 @@ export function useFormSchema(): VbenFormSchema[] {
|
||||
};
|
||||
};
|
||||
const results = queryString
|
||||
? options.filter(() => createFilter(queryString))
|
||||
? options.filter(createFilter(queryString))
|
||||
: options;
|
||||
cb(results);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user