feat:
1. 更新框架 2. 修复框架更新后导致的问题
This commit is contained in:
@@ -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:"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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 '';
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -68,7 +68,7 @@ const deleteApi = (row: any) => {
|
||||
<Page auto-content-height title="快递公司管理">
|
||||
<FormModal />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
|
||||
@@ -74,7 +74,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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="[
|
||||
|
||||
@@ -68,7 +68,7 @@ export const gridOptions: VxeGridProps<RegisterOrderItem> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -78,7 +78,7 @@ const deleteDictApi = (row: any) => {
|
||||
/>
|
||||
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<Button
|
||||
v-if="hasTopTableDropDownActions"
|
||||
danger
|
||||
|
||||
@@ -62,7 +62,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -143,7 +143,7 @@ const openDrugNumberBatchModal = () => {
|
||||
<DrugDetailModalComp />
|
||||
<FormModal />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -77,7 +77,7 @@ const collapseAll = () => {
|
||||
<Page auto-content-height title="商品分类管理">
|
||||
<FormModal />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:flex="false"
|
||||
:actions="[
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -280,7 +280,7 @@ const openExcelUploadModal = () => {
|
||||
<CentralStockInModalComp />
|
||||
<WarehousePriceModalComp />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:flex="false"
|
||||
:actions="[
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -227,7 +227,7 @@ const openExcelUploadModal = () => {
|
||||
<CentralStockInModalComp />
|
||||
<WarehousePriceModalComp />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:flex="false"
|
||||
:actions="[
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -223,7 +223,7 @@ const openExcelUploadModal = () => {
|
||||
<CentralStockInModalComp />
|
||||
<WarehousePriceModalComp />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:flex="false"
|
||||
:actions="[
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -206,7 +206,7 @@ const deleteApi = (row: any) => {
|
||||
<CentralStockInModalComp />
|
||||
<WarehousePriceModalComp />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -269,7 +269,7 @@ const openExcelUploadModal = () => {
|
||||
<CentralStockInModalComp />
|
||||
<WarehousePriceModalComp />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:flex="false"
|
||||
:actions="[
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -94,7 +94,7 @@ const deleteCategoryApi = (row: any) => {
|
||||
/>
|
||||
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<Button
|
||||
v-if="hasTopTableDropDownActions"
|
||||
danger
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -281,7 +281,7 @@ const deleteApi = (row?: any) => {
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<Button
|
||||
v-if="hasTopTableDropDownActions"
|
||||
danger
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -248,7 +248,7 @@ function onSpreadsheetConfigSaved() {
|
||||
/>
|
||||
</div>
|
||||
<Grid v-if="productType && viewMode === 'list'">
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -161,7 +161,7 @@ checkSubscribe();
|
||||
<ExcelUploadModal />
|
||||
<FormModal />
|
||||
<Grid v-if="productType">
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
// {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -176,7 +176,7 @@ checkSubscribe();
|
||||
<StorePriceBatchModalComp />
|
||||
<FormModal />
|
||||
<Grid v-if="productType">
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
|
||||
@@ -55,7 +55,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -68,7 +68,7 @@ const showDetail = (row: any) => {
|
||||
<FormModal />
|
||||
<DetailModal />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
|
||||
@@ -74,7 +74,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -152,7 +152,7 @@ const refuse = (id: number) => {
|
||||
<BindTitleModal />
|
||||
<DoctorCardModals />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
|
||||
@@ -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="[
|
||||
{
|
||||
|
||||
@@ -71,7 +71,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -106,7 +106,7 @@ const refuse = (id: number) => {
|
||||
<BindStoreModal />
|
||||
<PharmacistDetailModal />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
|
||||
@@ -67,7 +67,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -61,7 +61,7 @@ initTableAjax();
|
||||
:statistics="statistics"
|
||||
/>
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[]"
|
||||
:drop-down-actions="[]"
|
||||
|
||||
@@ -67,7 +67,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -66,7 +66,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -65,7 +65,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -71,7 +71,7 @@ initTableAjax();
|
||||
<MonthlyPaymentModal />
|
||||
<StatisticsReconciliation v-if="statistics" :statistics="statistics" />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction :actions="[
|
||||
{
|
||||
label: '结算订单',
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -69,7 +69,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -49,7 +49,7 @@ export const accountChangeGridOptions: VxeGridProps = {
|
||||
export: false,
|
||||
zoom: true,
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
},
|
||||
showOverflow: false,
|
||||
|
||||
@@ -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: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -85,7 +85,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -90,7 +90,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -53,7 +53,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -62,7 +62,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -62,7 +62,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -38,7 +38,7 @@ const showModal = (data = {}, isUpdate = false) => {
|
||||
<Page auto-content-height title="操作日志管理">
|
||||
<FormModal />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
]"
|
||||
|
||||
@@ -54,7 +54,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -55,7 +55,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -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 }">
|
||||
|
||||
@@ -190,7 +190,7 @@ onMounted(async () => {
|
||||
<DetailModalComp />
|
||||
<OpLogModalComp />
|
||||
<Grid>
|
||||
<template #toolbar-buttons />
|
||||
<template #toolbar-actions />
|
||||
<template #title="{ row }">
|
||||
<a
|
||||
class="cursor-pointer text-primary"
|
||||
|
||||
@@ -77,7 +77,7 @@ export function createGridOptions(category: number): VxeGridProps<any> {
|
||||
refresh: true,
|
||||
zoom: true,
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@ export const gridOptions: VxeGridProps<any> = {
|
||||
refresh: true,
|
||||
zoom: true,
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -108,7 +108,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
export: false,
|
||||
zoom: true,
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
},
|
||||
showOverflow: false,
|
||||
|
||||
@@ -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 }">
|
||||
|
||||
@@ -227,7 +227,7 @@ const copyToClipboard = async (text: string) => {
|
||||
<DoctorCardModals />
|
||||
<OaAccountModals />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
|
||||
@@ -168,7 +168,7 @@ export function createAdminGridOptions(
|
||||
export: false,
|
||||
zoom: true,
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
icon: 'vxe-icon-menu',
|
||||
|
||||
@@ -83,7 +83,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -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="[
|
||||
{
|
||||
|
||||
@@ -55,7 +55,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
||||
// custom: true, // 自定义列
|
||||
zoom: true, // 最大化最小化
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
buttons: 'toolbar-actions',
|
||||
},
|
||||
custom: {
|
||||
// 自定义列-图标
|
||||
|
||||
@@ -68,7 +68,7 @@ const showDetail = (row: any) => {
|
||||
<FormModal />
|
||||
<DetailModal />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -65,7 +65,7 @@ const deleteApi = (row: any) => {
|
||||
<Page auto-content-height title="仓药绑定管理">
|
||||
<FormModal />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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 }">
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -49,7 +49,7 @@ function auditTagColor(status: number) {
|
||||
<Page auto-content-height title="我的商品">
|
||||
<FormModal />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<template #toolbar-actions>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user