1. 更新框架
2. 修复框架更新后导致的问题
This commit is contained in:
李琦
2026-08-10 18:44:39 +08:00
parent 3547c53f89
commit f0a33a628b
150 changed files with 1005 additions and 811 deletions

View File

@@ -27,6 +27,7 @@
},
"dependencies": {
"@ant-design/icons-vue": "^7.0.1",
"@fortawesome/fontawesome-free": "^6.7.2",
"@vben/access": "workspace:*",
"@vben/common-ui": "workspace:*",
"@vben/constants": "workspace:*",
@@ -41,27 +42,26 @@
"@vben/styles": "workspace:*",
"@vben/types": "workspace:*",
"@vben/utils": "workspace:*",
"@vueup/vue-quill": "^1.2.0",
"@vueuse/core": "catalog:",
"ant-design-vue": "catalog:",
"axios": "^1.10.0",
"dayjs": "catalog:",
"exceljs": "^4.4.0",
"markdown-it": "^14.1.0",
"pinia": "catalog:",
"sortablejs": "catalog:",
"vue": "catalog:",
"vue-router": "catalog:",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@types/sortablejs": "catalog:",
"@fortawesome/fontawesome-free": "^6.7.2",
"@vueup/vue-quill": "^1.2.0",
"axios": "^1.10.0",
"html2canvas": "^1.4.1",
"js-base64": "^3.7.7",
"lodash-es": "^4.17.21",
"lucide-vue-next": "^0.487.0",
"markdown-it": "^14.1.0",
"md-editor-v3": "^5.4.5",
"xgplayer": "^3.0.24"
"pinia": "catalog:",
"sortablejs": "catalog:",
"vue": "catalog:",
"vue-router": "catalog:",
"xgplayer": "^3.0.24",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@types/sortablejs": "catalog:"
}
}

View File

@@ -68,6 +68,8 @@ import { isEmpty } from '@vben/utils';
import { message, Modal, notification } from 'ant-design-vue';
import { registerComponent } from '#/components/form/component-map';
type AdapterUploadProps = UploadProps & {
aspectRatio?: string;
crop?: boolean;
@@ -620,6 +622,8 @@ export type ComponentType =
| 'DatePicker'
| 'DefaultButton'
| 'Divider'
/** OA 场景表单的图片/文件素材选择(透传 acceptTypes 过滤类型) */
| 'GalleryPickLink'
| 'IconPicker'
| 'Input'
| 'InputNumber'
@@ -637,6 +641,10 @@ export type ComponentType =
| 'TimePicker'
| 'TreeSelect'
| 'Upload'
| 'UploadImage'
| 'UploadImageSortable'
| 'UploadOssFile'
| 'UploadDraggerPaste'
| BaseFormComponentType;
/**
@@ -737,6 +745,8 @@ async function initComponentAdapter() {
Upload: withPreviewUpload(),
};
// 自动注册 components/form 与 views/**/components/form 下的业务表单组件(如 Editor、Avatar
registerComponent(components);
// 将组件注册到全局共享状态中
globalShareState.setComponents(components);

View File

@@ -1,12 +1,12 @@
import type { SpreadsheetCommand } from '../types';
export function createSetCellValueCommand(
undo: () => void | Promise<void>,
redo: () => void | Promise<void>,
): SpreadsheetCommand {
import type { SpreadsheetCommand } from '../types';
export function createSetCellValueCommand(
undo: () => void | Promise<void>,
redo: () => void | Promise<void>,
): SpreadsheetCommand {
return {
label: 'setCellValue',
undo,
redo,
};
}

View File

@@ -1,7 +1,7 @@
import type { CustomComponentType } from './types';
import type { Component } from 'vue';
import type { CustomComponentType } from './types';
import { getFileNameWithoutExtension, toPascalCase } from '#/util/tool';
const componentMap = new Map<CustomComponentType | string, Component>();

View File

@@ -1,346 +1,346 @@
<script setup lang="ts">
import { computed, nextTick, ref, watch } from 'vue';
import { useDebounceFn, useVModel } from '@vueuse/core';
import { Avatar, Empty, Input, Popover, Spin, Tabs, Tag } from 'ant-design-vue';
import { searchApiLogUsers } from '#/views/log/api-log/api';
defineOptions({
name: 'ApiLogUserPicker',
inheritAttrs: false,
});
export type ApiLogUserFilter = {
id: number;
user_type: 'admin' | 'patient' | 'doctor';
platform_type: 0 | 1 | 2;
name: string;
role_label: string;
avatar?: string;
};
type ApiLogUserOption = ApiLogUserFilter;
type UserTab = 'admin' | 'patient' | 'doctor';
const props = defineProps<{
value?: ApiLogUserFilter;
disabled?: boolean;
onPlatformTypeChange?: (platformType: 0 | 1 | 2) => void;
}>();
const emits = defineEmits<{
'update:value': [value: ApiLogUserFilter | undefined];
}>();
const mValue = useVModel(props, 'value', emits, { passive: true });
const open = ref(false);
const loading = ref(false);
const searchKeyword = ref('');
const activeTab = ref<UserTab>('admin');
const options = ref<ApiLogUserOption[]>([]);
const searchInputRef = ref<InstanceType<typeof Input> | null>(null);
const TAB_ITEMS = [
{ key: 'admin', label: '后台用户' },
{ key: 'patient', label: '患者端用户' },
{ key: 'doctor', label: '医生端用户' },
] as const;
const searchPlaceholder = computed(() => {
if (activeTab.value === 'admin') return '搜索手机号或昵称';
if (activeTab.value === 'patient') return '搜索用户名字';
return '搜索名字或手机号';
});
async function fetchOptions() {
const keyword = searchKeyword.value.trim();
if (!keyword) {
options.value = [];
return;
}
loading.value = true;
try {
const result = await searchApiLogUsers({
user_type: activeTab.value,
keyword,
pageSize: 24,
});
options.value = result?.items ?? [];
} finally {
loading.value = false;
}
}
const debouncedFetch = useDebounceFn(fetchOptions, 300);
watch([searchKeyword, activeTab], () => {
debouncedFetch();
});
function selectOption(item: ApiLogUserOption) {
mValue.value = {
id: item.id,
user_type: item.user_type,
platform_type: item.platform_type,
name: item.name,
role_label: item.role_label,
avatar: item.avatar,
};
props.onPlatformTypeChange?.(item.platform_type);
open.value = false;
searchKeyword.value = '';
options.value = [];
}
function clearSelection(e: Event) {
e.stopPropagation();
mValue.value = undefined;
}
function onOpenChange(next: boolean) {
if (props.disabled) return;
open.value = next;
if (next) {
searchKeyword.value = '';
options.value = [];
nextTick(() => searchInputRef.value?.focus?.());
}
}
watch(
() => props.disabled,
(disabled) => {
if (disabled) open.value = false;
},
);
</script>
<template>
<Popover
:open="open"
trigger="click"
placement="bottomLeft"
overlay-class-name="api-log-user-picker-popover"
@open-change="onOpenChange"
>
<template #content>
<div class="api-log-user-panel">
<Tabs v-model:active-key="activeTab" size="small" class="api-log-user-tabs">
<Tabs.TabPane
v-for="tab in TAB_ITEMS"
:key="tab.key"
:tab="tab.label"
/>
</Tabs>
<Input
ref="searchInputRef"
v-model:value="searchKeyword"
allow-clear
:placeholder="searchPlaceholder"
class="api-log-user-search"
/>
<Spin :spinning="loading">
<div v-if="options.length" class="api-log-user-grid">
<button
v-for="item in options"
:key="`${item.user_type}-${item.id}`"
type="button"
class="api-log-user-card"
:class="{
active:
mValue?.id === item.id && mValue?.user_type === item.user_type,
}"
@click="selectOption(item)"
>
<Avatar :src="item.avatar" :size="30">
{{ (item.name || '?').charAt(0) }}
</Avatar>
<div class="api-log-user-card-id">#{{ item.id }}</div>
<div class="api-log-user-card-name" :title="item.name">
{{ item.name }}
</div>
<Tag class="api-log-user-card-role" :bordered="false">
{{ item.role_label }}
</Tag>
</button>
</div>
<Empty
v-else
:description="searchKeyword.trim() ? '无匹配用户' : '请输入关键词搜索'"
<script setup lang="ts">
import { computed, nextTick, ref, watch } from 'vue';
import { useDebounceFn, useVModel } from '@vueuse/core';
import { Avatar, Empty, Input, Popover, Spin, Tabs, Tag } from 'ant-design-vue';
import { searchApiLogUsers } from '#/views/log/api-log/api';
defineOptions({
name: 'ApiLogUserPicker',
inheritAttrs: false,
});
export type ApiLogUserFilter = {
id: number;
user_type: 'admin' | 'patient' | 'doctor';
platform_type: 0 | 1 | 2;
name: string;
role_label: string;
avatar?: string;
};
type ApiLogUserOption = ApiLogUserFilter;
type UserTab = 'admin' | 'patient' | 'doctor';
const props = defineProps<{
value?: ApiLogUserFilter;
disabled?: boolean;
onPlatformTypeChange?: (platformType: 0 | 1 | 2) => void;
}>();
const emits = defineEmits<{
'update:value': [value: ApiLogUserFilter | undefined];
}>();
const mValue = useVModel(props, 'value', emits, { passive: true });
const open = ref(false);
const loading = ref(false);
const searchKeyword = ref('');
const activeTab = ref<UserTab>('admin');
const options = ref<ApiLogUserOption[]>([]);
const searchInputRef = ref<InstanceType<typeof Input> | null>(null);
const TAB_ITEMS = [
{ key: 'admin', label: '后台用户' },
{ key: 'patient', label: '患者端用户' },
{ key: 'doctor', label: '医生端用户' },
] as const;
const searchPlaceholder = computed(() => {
if (activeTab.value === 'admin') return '搜索手机号或昵称';
if (activeTab.value === 'patient') return '搜索用户名字';
return '搜索名字或手机号';
});
async function fetchOptions() {
const keyword = searchKeyword.value.trim();
if (!keyword) {
options.value = [];
return;
}
loading.value = true;
try {
const result = await searchApiLogUsers({
user_type: activeTab.value,
keyword,
pageSize: 24,
});
options.value = result?.items ?? [];
} finally {
loading.value = false;
}
}
const debouncedFetch = useDebounceFn(fetchOptions, 300);
watch([searchKeyword, activeTab], () => {
debouncedFetch();
});
function selectOption(item: ApiLogUserOption) {
mValue.value = {
id: item.id,
user_type: item.user_type,
platform_type: item.platform_type,
name: item.name,
role_label: item.role_label,
avatar: item.avatar,
};
props.onPlatformTypeChange?.(item.platform_type);
open.value = false;
searchKeyword.value = '';
options.value = [];
}
function clearSelection(e: Event) {
e.stopPropagation();
mValue.value = undefined;
}
function onOpenChange(next: boolean) {
if (props.disabled) return;
open.value = next;
if (next) {
searchKeyword.value = '';
options.value = [];
nextTick(() => searchInputRef.value?.focus?.());
}
}
watch(
() => props.disabled,
(disabled) => {
if (disabled) open.value = false;
},
);
</script>
<template>
<Popover
:open="open"
trigger="click"
placement="bottomLeft"
overlay-class-name="api-log-user-picker-popover"
@open-change="onOpenChange"
>
<template #content>
<div class="api-log-user-panel">
<Tabs v-model:active-key="activeTab" size="small" class="api-log-user-tabs">
<Tabs.TabPane
v-for="tab in TAB_ITEMS"
:key="tab.key"
:tab="tab.label"
/>
</Tabs>
<Input
ref="searchInputRef"
v-model:value="searchKeyword"
allow-clear
:placeholder="searchPlaceholder"
class="api-log-user-search"
/>
<Spin :spinning="loading">
<div v-if="options.length" class="api-log-user-grid">
<button
v-for="item in options"
:key="`${item.user_type}-${item.id}`"
type="button"
class="api-log-user-card"
:class="{
active:
mValue?.id === item.id && mValue?.user_type === item.user_type,
}"
@click="selectOption(item)"
>
<Avatar :src="item.avatar" :size="30">
{{ (item.name || '?').charAt(0) }}
</Avatar>
<div class="api-log-user-card-id">#{{ item.id }}</div>
<div class="api-log-user-card-name" :title="item.name">
{{ item.name }}
</div>
<Tag class="api-log-user-card-role" :bordered="false">
{{ item.role_label }}
</Tag>
</button>
</div>
<Empty
v-else
:description="searchKeyword.trim() ? '无匹配用户' : '请输入关键词搜索'"
class="api-log-user-empty"
/>
</Spin>
</div>
</template>
<div class="api-log-user-trigger" :class="{ disabled: disabled }">
<div v-if="mValue" class="api-log-selected-card">
<Avatar :src="mValue.avatar" :size="36">
{{ (mValue.name || '?').charAt(0) }}
</Avatar>
<div class="api-log-selected-meta">
<div class="api-log-selected-name">{{ mValue.name }}</div>
<div class="api-log-selected-sub">
#{{ mValue.id }} · {{ mValue.role_label }}
</div>
</div>
<span
v-if="!disabled"
class="api-log-clear-btn"
@click="clearSelection"
>
×
</span>
</div>
<div v-else class="api-log-trigger-placeholder">请选择操作用户</div>
</div>
</Popover>
</template>
<style scoped lang="scss">
@use './picker-card-theme.scss' as theme;
.api-log-user-trigger {
width: 100%;
}
.api-log-user-trigger.disabled {
cursor: not-allowed;
opacity: 0.65;
}
.api-log-user-trigger:not(.disabled) {
cursor: pointer;
}
.api-log-selected-card {
@include theme.picker-selected-card;
}
.api-log-selected-meta {
min-width: 0;
flex: 1;
}
.api-log-selected-name {
font-size: 14px;
font-weight: 500;
color: #1d2129;
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.api-log-selected-sub {
font-size: 12px;
color: #86909c;
line-height: 1.4;
}
.api-log-trigger-placeholder {
@include theme.picker-trigger-placeholder;
}
.api-log-clear-btn {
@include theme.picker-clear-btn;
}
.dark {
.api-log-selected-card {
@include theme.picker-selected-card-dark-props;
}
.api-log-selected-name {
@include theme.picker-text-primary-dark;
}
.api-log-selected-sub {
@include theme.picker-text-secondary-dark;
}
.api-log-trigger-placeholder {
@include theme.picker-placeholder-dark-props;
}
.api-log-clear-btn {
@include theme.picker-clear-dark-props;
}
}
</style>
<style lang="scss">
@use './picker-card-theme.scss' as theme;
.api-log-user-picker-popover {
.ant-popover-inner {
padding: 12px;
}
.api-log-user-panel {
width: 540px;
max-width: 86vw;
}
.api-log-user-tabs {
margin-bottom: 8px;
}
.api-log-user-search {
margin-bottom: 10px;
}
.api-log-user-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
gap: 8px;
max-height: 300px;
overflow-y: auto;
padding: 2px;
}
.api-log-user-card {
@include theme.picker-card-base;
}
.api-log-user-card-id {
@include theme.picker-card-sub;
}
.api-log-user-card-name {
@include theme.picker-card-name;
}
.api-log-user-card-role {
margin: 0;
font-size: 11px;
line-height: 18px;
padding: 0 6px;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
.api-log-user-empty {
margin: 16px 0;
}
}
.dark .api-log-user-picker-popover {
.api-log-user-card {
@include theme.picker-card-dark-props;
}
.api-log-user-card-name {
@include theme.picker-text-primary-dark;
}
.api-log-user-card-id {
@include theme.picker-text-secondary-dark;
}
}
</style>

View File

@@ -1,9 +1,9 @@
<script setup lang="ts">
import { ref } from 'vue';
import { preferences } from '@vben/preferences';
import { QuillEditor } from '@vueup/vue-quill';
// eslint-disable-next-line n/no-extraneous-import
import '@vueup/vue-quill/dist/vue-quill.snow.css';
import { useVModel } from '@vueuse/core';
import { message } from 'ant-design-vue';
@@ -11,7 +11,9 @@ import { message } from 'ant-design-vue';
import { uploadFile } from '#/api/core/upload';
import { uploadToOss } from '#/utils/oss-upload';
import { prepareImageForUpload } from '#/utils/prepare-image-upload';
import { preferences } from '@vben/preferences';
// eslint-disable-next-line n/no-extraneous-import
import '@vueup/vue-quill/dist/vue-quill.snow.css';
const props = defineProps({
value: {
@@ -140,26 +142,26 @@ const insertImageToEditor = (quill: any, imageUrl: string): void => {
};
/**
* 图片上传函数
*
*
* 该函数根据preferences配置的上传方式选择使用OSS直传或后端上传
* - 'direct': OSS直传模式文件直接从浏览器上传到阿里云OSS
* - 'backend': 后端上传模式文件先上传到后端服务器再由后端上传到OSS
*
*
* 上传方式说明:
* 1. OSS直传direct
* - 调用uploadToOss函数直接上传到OSS
* - 减少服务器负载,上传速度更快
* - 支持上传进度回调(如果需要可以添加)
*
*
* 2. 后端上传backend
* - 调用uploadFile API通过后端服务器上传
* - 兼容现有功能,所有上传逻辑由后端统一处理
*
*
* 兼容性处理:
* - 两种上传方式返回的数据结构保持一致:{ url: string }
* - 上传成功或失败都会显示相应的提示信息
* - 上传完成后将isUpload标记设置为false允许下次上传
*
*
* @param {File} file - 要上传的图片文件
* @returns {Promise<string>} - 返回上传后的图片URL如果上传失败返回空字符串
*/
@@ -205,22 +207,22 @@ const uploadImage = async (file: File): Promise<string> => {
key: 'imageUpload',
duration: 2,
});
// 重置上传标记,允许下次上传
isUpload.value = false;
// 返回上传后的图片URL
return data.url;
} catch (error) {
// 处理上传错误
console.error('图片上传错误:', error);
// 显示错误提示
message.error({ content: '图片上传失败', key: 'imageUpload', duration: 2 });
// 重置上传标记,允许重试
isUpload.value = false;
// 返回空字符串,表示上传失败
return '';
}

View File

@@ -1,60 +1,60 @@
/**
* 中药处方毛利率计算(仅商品计费,不含诊疗费/加工费)
*/
export function isSeeRateEnabled(seeRate: unknown): boolean {
return Number(seeRate) === 1;
}
function isValidBuyPrice(value: unknown): boolean {
if (value === null || value === undefined || value === '') {
return false;
}
const n = Number(value);
return !Number.isNaN(n);
}
export function calcItemMarginPercent(
price: number | string | undefined,
buyPrice: number | string | undefined,
): string {
const p = Number(price);
if (!p || p <= 0 || !isValidBuyPrice(buyPrice)) {
return '--';
}
const b = Number(buyPrice);
return (((p - b) / p) * 100).toFixed(2);
}
export interface ChineseDrugMarginRow {
price?: number | string;
/**
* 中药处方毛利率计算(仅商品计费,不含诊疗费/加工费)
*/
export function isSeeRateEnabled(seeRate: unknown): boolean {
return Number(seeRate) === 1;
}
function isValidBuyPrice(value: unknown): boolean {
if (value === null || value === undefined || value === '') {
return false;
}
const n = Number(value);
return !Number.isNaN(n);
}
export function calcItemMarginPercent(
price: number | string | undefined,
buyPrice: number | string | undefined,
): string {
const p = Number(price);
if (!p || p <= 0 || !isValidBuyPrice(buyPrice)) {
return '--';
}
const b = Number(buyPrice);
return (((p - b) / p) * 100).toFixed(2);
}
export interface ChineseDrugMarginRow {
price?: number | string;
buy_price?: number | string;
number?: number | string;
select_number?: number | string;
}
export function calcTotalMarginPercent(
drugs: ChineseDrugMarginRow[],
dosage: number,
): string {
if (!drugs?.length || dosage <= 0) {
return '0.00';
}
let saleTotal = 0;
let buyTotal = 0;
for (const drug of drugs) {
if (!isValidBuyPrice(drug.buy_price)) {
return '--';
}
const qty = Number(drug.number ?? drug.select_number ?? 1);
const price = Number(drug.price || 0);
const buyPrice = Number(drug.buy_price);
saleTotal += price * qty * dosage;
buyTotal += buyPrice * qty * dosage;
}
if (saleTotal <= 0) {
return '0.00';
}
return (((saleTotal - buyTotal) / saleTotal) * 100).toFixed(2);
}

View File

@@ -56,7 +56,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -68,7 +68,7 @@ const deleteApi = (row: any) => {
<Page auto-content-height title="快递公司管理">
<FormModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -74,7 +74,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -102,7 +102,7 @@ const openPrescriptionSourceModal = (id: number) => {
</Tabs>
</div>
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction :actions="[]" :drop-down-actions="[]">
<template #more>
<Button style="margin-left: 16px">

View File

@@ -121,7 +121,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -869,7 +869,7 @@ const openOrderAmountVerify = () => {
<ChinaErpSyncDrawer @synced="() => gridApi.query()" />
<AnalysisOverview :items="overviewItems" :my-card="false" />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:flex="false"
:actions="[

View File

@@ -68,7 +68,7 @@ export const gridOptions: VxeGridProps<RegisterOrderItem> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -121,7 +121,7 @@ function formatRegisterPrice(price: unknown) {
<RefundModal />
<StoreCardModalComp />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction :actions="[]" :drop-down-actions="[]">
<template #more>
<Button style="margin-left: 16px">

View File

@@ -69,7 +69,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -78,7 +78,7 @@ const deleteDictApi = (row: any) => {
/>
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<Button
v-if="hasTopTableDropDownActions"
danger

View File

@@ -62,7 +62,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -143,7 +143,7 @@ const openDrugNumberBatchModal = () => {
<DrugDetailModalComp />
<FormModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -77,7 +77,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -77,7 +77,7 @@ const collapseAll = () => {
<Page auto-content-height title="商品分类管理">
<FormModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:flex="false"
:actions="[

View File

@@ -89,7 +89,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -280,7 +280,7 @@ const openExcelUploadModal = () => {
<CentralStockInModalComp />
<WarehousePriceModalComp />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:flex="false"
:actions="[

View File

@@ -82,7 +82,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -227,7 +227,7 @@ const openExcelUploadModal = () => {
<CentralStockInModalComp />
<WarehousePriceModalComp />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:flex="false"
:actions="[

View File

@@ -82,7 +82,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -223,7 +223,7 @@ const openExcelUploadModal = () => {
<CentralStockInModalComp />
<WarehousePriceModalComp />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:flex="false"
:actions="[

View File

@@ -82,7 +82,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -206,7 +206,7 @@ const deleteApi = (row: any) => {
<CentralStockInModalComp />
<WarehousePriceModalComp />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -99,7 +99,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -269,7 +269,7 @@ const openExcelUploadModal = () => {
<CentralStockInModalComp />
<WarehousePriceModalComp />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:flex="false"
:actions="[

View File

@@ -55,7 +55,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -94,7 +94,7 @@ const deleteCategoryApi = (row: any) => {
/>
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<Button
v-if="hasTopTableDropDownActions"
danger

View File

@@ -109,7 +109,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -281,7 +281,7 @@ const deleteApi = (row?: any) => {
</template>
</template>
<template #toolbar-buttons>
<template #toolbar-actions>
<Button
v-if="hasTopTableDropDownActions"
danger

View File

@@ -63,7 +63,7 @@ export function createGridOptions(productType: number): VxeGridProps<RowType> {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -248,7 +248,7 @@ function onSpreadsheetConfigSaved() {
/>
</div>
<Grid v-if="productType && viewMode === 'list'">
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -64,7 +64,7 @@ export function createGridOptions(productType: number): VxeGridProps<RowType> {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -161,7 +161,7 @@ checkSubscribe();
<ExcelUploadModal />
<FormModal />
<Grid v-if="productType">
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
// {

View File

@@ -75,7 +75,7 @@ export function createGridOptions(productType: number): VxeGridProps<RowType> {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -176,7 +176,7 @@ checkSubscribe();
<StorePriceBatchModalComp />
<FormModal />
<Grid v-if="productType">
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -55,7 +55,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -68,7 +68,7 @@ const showDetail = (row: any) => {
<FormModal />
<DetailModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -74,7 +74,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -152,7 +152,7 @@ const refuse = (id: number) => {
<BindTitleModal />
<DoctorCardModals />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -108,7 +108,7 @@ const gridOptions = computed(() => ({
toolbarConfig: {
search: true,
refresh: true,
slots: { buttons: 'toolbar-buttons' },
slots: { buttons: 'toolbar-actions' },
},
}));
@@ -245,7 +245,7 @@ function handleSyncPinyin() {
<Page auto-content-height :title="pageTitle">
<FormModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -71,7 +71,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -106,7 +106,7 @@ const refuse = (id: number) => {
<BindStoreModal />
<PharmacistDetailModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -67,7 +67,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -61,7 +61,7 @@ initTableAjax();
:statistics="statistics"
/>
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[]"
:drop-down-actions="[]"

View File

@@ -67,7 +67,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -38,7 +38,7 @@ const infoModal = (id) => {
<OrderDetailModal />
<StatisticsReconciliation v-if="statistics" :statistics="statistics" />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction :actions="[]" :drop-down-actions="[]">
<template #more>
<Button style="margin-left: 16px">

View File

@@ -63,7 +63,7 @@ export function createGridOptions(getStatus: () => string | number): VxeGridProp
print: false,
export: false,
zoom: true,
slots: { buttons: 'toolbar-buttons' },
slots: { buttons: 'toolbar-actions' },
},
showOverflow: false,
};

View File

@@ -202,7 +202,7 @@ onMounted(() => {
<Tabs.TabPane key="all" tab="全部" />
</Tabs>
<Grid>
<template #toolbar-buttons />
<template #toolbar-actions />
<template #status="{ row }">
<Tag :color="statusColor(row.status)">{{ row.status_text }}</Tag>
</template>

View File

@@ -66,7 +66,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -39,7 +39,7 @@ const infoModal = (id) => {
<MonthlyPaymentModal />
<StatisticsReconciliation v-if="statistics" :statistics="statistics" />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction :actions="[]" :drop-down-actions="[]">
<template #more>
<Button style="margin-left: 16px">

View File

@@ -65,7 +65,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -71,7 +71,7 @@ initTableAjax();
<MonthlyPaymentModal />
<StatisticsReconciliation v-if="statistics" :statistics="statistics" />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction :actions="[
{
label: '结算订单',

View File

@@ -51,7 +51,7 @@ export const gridOptions: VxeGridProps<RowType> = {
print: false,
export: false,
zoom: true,
slots: { buttons: 'toolbar-buttons' },
slots: { buttons: 'toolbar-actions' },
},
showOverflow: false,
};

View File

@@ -69,7 +69,7 @@ function openPreview(files: string[]) {
<CompleteModalComp />
<FilePreviewModal v-model:open="previewOpen" :files="previewFiles" title="发票预览" />
<Grid>
<template #toolbar-buttons />
<template #toolbar-actions />
<template #status="{ row }">
<Tag :color="partyStatusColor(row.status)">
{{ row.status_text }}

View File

@@ -69,7 +69,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -44,7 +44,7 @@ const infoModal = (id, modalType = 0) => {
<WithdrawalAuditModal />
<StatisticsReconciliation v-if="statistics" :statistics="statistics" />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction :actions="[]" :drop-down-actions="[]">
<template #more>
<Button style="margin-left: 16px">

View File

@@ -49,7 +49,7 @@ export const accountChangeGridOptions: VxeGridProps = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
},
showOverflow: false,

View File

@@ -67,7 +67,7 @@ export const gridOptions2: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标
@@ -134,7 +134,7 @@ export const gridOptions3: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -85,7 +85,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -112,7 +112,7 @@ function updateShowStatus() {
<template #trends>
<div style="min-height: 500px">
<Grid>
<template #toolbar-buttons></template>
<template #toolbar-actions></template>
<template #toolbar-tools></template>
<template #user_id="{ row }">
<span v-if="row.user_type === 1">{{ row.store?.name }}</span>
@@ -161,7 +161,7 @@ function updateShowStatus() {
<template #visits>
<div style="min-height: 500px">
<Grid3>
<template #toolbar-buttons></template>
<template #toolbar-actions></template>
<template #toolbar-tools></template>
<template #action="{ row }">
<TableAction
@@ -189,7 +189,7 @@ function updateShowStatus() {
<template #visitsItems>
<div style="min-height: 500px">
<Grid2>
<template #toolbar-buttons></template>
<template #toolbar-actions></template>
<template #toolbar-tools></template>
<template #user_id="{ row }">
<span v-if="row.user_type === 1">{{ row.store?.name }}</span>
@@ -211,7 +211,7 @@ function updateShowStatus() {
<template #accountChange>
<div style="min-height: 500px">
<Grid4>
<template #toolbar-buttons></template>
<template #toolbar-actions></template>
<template #toolbar-tools></template>
<template #change_amount="{ row }">
<span

View File

@@ -90,7 +90,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -63,7 +63,7 @@ const showModal = (data = {}, isUpdate = false) => {
<Page auto-content-height title="Api访问日志管理">
<FormModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
</template>
<template #type="{ row }">
<Tag v-if="row.type === 0" color="green"> 访问成功 </Tag>

View File

@@ -53,7 +53,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -38,7 +38,7 @@ const showModal = (data = {}, isUpdate = false) => {
<Page auto-content-height title="分账日志管理">
<FormModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
</template>
<template #store="{ row }">
<span v-if="row.user_type === 1">{{ row.store.name }}</span>

View File

@@ -62,7 +62,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -38,7 +38,7 @@ const showModal = (data = {}, isUpdate = false) => {
<Page auto-content-height title="Api访问日志管理">
<FormModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
</template>
<template #type="{ row }">
<Tag v-if="row.type === 0" color="green"> 访问成功 </Tag>

View File

@@ -62,7 +62,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -38,7 +38,7 @@ const showModal = (data = {}, isUpdate = false) => {
<Page auto-content-height title="操作日志管理">
<FormModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
]"

View File

@@ -54,7 +54,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -38,7 +38,7 @@ const showModal = (data = {}, isUpdate = false) => {
<Page auto-content-height title="订单日志管理">
<FormModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
</template>
<template #logo="{ row }">
<Image :src="row.logo" height="30" width="30" />

View File

@@ -55,7 +55,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -38,7 +38,7 @@ const showModal = (data = {}, isUpdate = false) => {
<Page auto-content-height title="处方日志管理">
<FormModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
</template>
<template #toolbar-tools></template>
<template #action="{ row }">

View File

@@ -190,7 +190,7 @@ onMounted(async () => {
<DetailModalComp />
<OpLogModalComp />
<Grid>
<template #toolbar-buttons />
<template #toolbar-actions />
<template #title="{ row }">
<a
class="cursor-pointer text-primary"

View File

@@ -77,7 +77,7 @@ export function createGridOptions(category: number): VxeGridProps<any> {
refresh: true,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
},
};

View File

@@ -55,7 +55,7 @@ export const gridOptions: VxeGridProps<any> = {
refresh: true,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
},
};

View File

@@ -80,7 +80,7 @@ onMounted(async () => {
<Page auto-content-height title="仓库修改记录">
<DetailModalComp />
<Grid>
<template #toolbar-buttons />
<template #toolbar-actions />
<template #user_type="{ row }">
<Tag :color="Number(row.user_type) === 2 ? 'geekblue' : 'green'">
{{ row.user_type_txt || row.user_type }}

View File

@@ -108,7 +108,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
},
showOverflow: false,

View File

@@ -258,7 +258,7 @@ function onViewModeChange(mode: string | number) {
/>
</div>
<Grid v-if="viewMode === 'list'">
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction :actions="[]" :drop-down-actions="[]" />
</template>
<template #prescription_no="{ row }">

View File

@@ -227,7 +227,7 @@ const copyToClipboard = async (text: string) => {
<DoctorCardModals />
<OaAccountModals />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -168,7 +168,7 @@ export function createAdminGridOptions(
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -83,7 +83,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -81,7 +81,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
toolbarConfig: {
search: true,
refresh: true,
slots: { buttons: 'toolbar-buttons' },
slots: { buttons: 'toolbar-actions' },
},
},
gridEvents: {
@@ -139,7 +139,7 @@ onMounted(async () => {
<Page auto-content-height>
<FormModalComp />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -55,7 +55,7 @@ export const gridOptions: VxeGridProps<RowType> = {
// custom: true, // 自定义列
zoom: true, // 最大化最小化
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
// 自定义列-图标

View File

@@ -68,7 +68,7 @@ const showDetail = (row: any) => {
<FormModal />
<DetailModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -79,7 +79,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -65,7 +65,7 @@ const deleteApi = (row: any) => {
<Page auto-content-height title="仓药绑定管理">
<FormModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -64,7 +64,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -85,7 +85,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -49,7 +49,7 @@ function auditTagColor(status: number) {
<Page auto-content-height title="仓品审核">
<AuditModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction :actions="[]" :drop-down-actions="[]" />
</template>
<template #image="{ row }">

View File

@@ -85,7 +85,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -49,7 +49,7 @@ function auditTagColor(status: number) {
<Page auto-content-height title="我的商品">
<FormModal />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

View File

@@ -57,7 +57,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -66,7 +66,7 @@ export const gridOptions: VxeGridProps<RowType> = {
export: false,
zoom: true,
slots: {
buttons: 'toolbar-buttons',
buttons: 'toolbar-actions',
},
custom: {
icon: 'vxe-icon-menu',

View File

@@ -122,7 +122,7 @@ const deleteApi = (row: any) => {
<BankCardReportModalComponent />
<BankCardStatusModalComponent />
<Grid>
<template #toolbar-buttons>
<template #toolbar-actions>
<TableAction
:actions="[
{

Some files were not shown because too many files have changed in this diff Show More