fix: 接诊UI
This commit is contained in:
@@ -237,7 +237,7 @@ async function onSelectDrug(item: any) {
|
||||
class="w-[40%]"
|
||||
>
|
||||
<div class="mb-4">
|
||||
<div class="mb-1 text-sm text-gray-600">
|
||||
<div class="mb-1 text-sm text-muted-foreground">
|
||||
药品
|
||||
<span class="text-red-500">*</span>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
const prefix = 'delivery-warehouse-product/';
|
||||
|
||||
/**
|
||||
* 平台仓品审核列表
|
||||
* audit_status 为空时后端默认只返回待审
|
||||
*/
|
||||
export async function getDeliveryWarehouseProductAuditList(data: any) {
|
||||
return requestClient.get<any>(`${prefix}audit-list`, { params: data });
|
||||
}
|
||||
|
||||
/**
|
||||
* 仓品详情(审核弹窗展示)
|
||||
*/
|
||||
export async function getDeliveryWarehouseProductInfo(id: number) {
|
||||
return requestClient.get<any>(`${prefix}detail`, { params: { id } });
|
||||
}
|
||||
|
||||
/**
|
||||
* 平台审核:status 必为 2 下架或 3 上架;需填 zone_id
|
||||
*/
|
||||
export async function auditDeliveryWarehouseProduct(data: {
|
||||
id: number;
|
||||
status: 2 | 3;
|
||||
zone_id: number;
|
||||
category_id?: number;
|
||||
}) {
|
||||
return requestClient.post<any>(`${prefix}audit`, data);
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
<script lang="ts" setup>
|
||||
/**
|
||||
* 平台仓品审核弹窗
|
||||
* 必选上架/下架 + 所属分区;审核成功后由列表页打开仓药绑定弹窗
|
||||
*/
|
||||
import { nextTick, ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { Descriptions, Image, message, Tag } from 'ant-design-vue';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { getDrugCategoriesTree, getZoneOptions } from '#/views/business/product/drug-categories/api';
|
||||
|
||||
import {
|
||||
auditDeliveryWarehouseProduct,
|
||||
getDeliveryWarehouseProductInfo,
|
||||
} from '../api';
|
||||
|
||||
const gridApi = ref();
|
||||
const detail = ref<Record<string, any> | null>(null);
|
||||
/** 审核成功后回传给列表页,用于打开绑仓弹窗 */
|
||||
const onBindPreset = ref<((preset: Record<string, any>) => void) | null>(null);
|
||||
|
||||
const [Form, formApi] = useVbenForm({
|
||||
wrapperClass: 'grid-cols-12',
|
||||
commonConfig: {
|
||||
formItemClass: 'col-span-12',
|
||||
componentProps: {
|
||||
class: 'w-full',
|
||||
},
|
||||
},
|
||||
layout: 'horizontal',
|
||||
schema: [
|
||||
{
|
||||
component: 'VbenInput',
|
||||
fieldName: 'id',
|
||||
label: 'ID',
|
||||
dependencies: {
|
||||
show: false,
|
||||
triggerFields: ['id'],
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
api: getZoneOptions,
|
||||
labelField: 'title',
|
||||
valueField: 'id',
|
||||
placeholder: '请选择分区',
|
||||
allowClear: false,
|
||||
},
|
||||
fieldName: 'zone_id',
|
||||
label: '所属分区',
|
||||
rules: 'selectRequired',
|
||||
},
|
||||
{
|
||||
component: 'ApiTreeSelect',
|
||||
componentProps: {
|
||||
api: getDrugCategoriesTree,
|
||||
childrenField: 'children',
|
||||
labelField: 'category_name',
|
||||
valueField: 'id',
|
||||
placeholder: '请先选择分区',
|
||||
allowClear: true,
|
||||
treeDefaultExpandAll: true,
|
||||
immediate: false,
|
||||
alwaysLoad: true,
|
||||
},
|
||||
fieldName: 'category_id',
|
||||
label: '所属分类',
|
||||
dependencies: {
|
||||
componentProps(values, formApiInst) {
|
||||
return {
|
||||
beforeFetch: async () => {
|
||||
const currentValues = await formApiInst.getValues();
|
||||
return { zone_id: currentValues.zone_id };
|
||||
},
|
||||
placeholder: values.zone_id ? '请选择分类' : '请先选择分区',
|
||||
};
|
||||
},
|
||||
trigger(_values, formApiInst) {
|
||||
formApiInst.setFieldValue('category_id', undefined);
|
||||
},
|
||||
triggerFields: ['zone_id'],
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '上架', value: 3 },
|
||||
{ label: '下架', value: 2 },
|
||||
],
|
||||
},
|
||||
fieldName: 'status',
|
||||
label: '审核结果',
|
||||
rules: 'selectRequired',
|
||||
help: '审核通过后按所选结果上架或下架,并打开绑仓弹窗',
|
||||
},
|
||||
],
|
||||
showDefaultActions: false,
|
||||
});
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
fullscreenButton: false,
|
||||
draggable: true,
|
||||
onCancel() {
|
||||
modalApi.close();
|
||||
},
|
||||
onConfirm: async () => {
|
||||
formApi.validate().then(async (e: any) => {
|
||||
if (e.valid) {
|
||||
const values = await formApi.getValues();
|
||||
const status = Number(values.status);
|
||||
if (status !== 2 && status !== 3) {
|
||||
message.warning('请选择上架或下架');
|
||||
return;
|
||||
}
|
||||
if (!values.zone_id) {
|
||||
message.warning('请选择所属分区');
|
||||
return;
|
||||
}
|
||||
modalApi.setState({ loading: true, confirmLoading: true });
|
||||
auditDeliveryWarehouseProduct({
|
||||
id: Number(values.id),
|
||||
status: status as 2 | 3,
|
||||
zone_id: Number(values.zone_id),
|
||||
category_id: Number(values.category_id || 0),
|
||||
})
|
||||
.then((res: any) => {
|
||||
message.success('审核成功,请完成仓药绑定');
|
||||
gridApi.value?.query?.() ?? gridApi.value?.reload?.();
|
||||
const preset = res?.bind_preset || res?.data?.bind_preset;
|
||||
modalApi.close();
|
||||
if (preset && onBindPreset.value) {
|
||||
nextTick(() => onBindPreset.value?.(preset));
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
modalApi.setState({ loading: false, confirmLoading: false });
|
||||
});
|
||||
}
|
||||
});
|
||||
await formApi.validateAndSubmitForm();
|
||||
},
|
||||
async onOpenChange(isOpen: boolean) {
|
||||
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
|
||||
onBindPreset.value = isOpen ? modalApi.getData()?.onBindPreset || null : null;
|
||||
if (!isOpen) {
|
||||
detail.value = null;
|
||||
return;
|
||||
}
|
||||
await formApi.resetForm();
|
||||
const data = modalApi.getData<Record<string, any>>() || {};
|
||||
const id = Number(data.id || data.values?.id || 0);
|
||||
await formApi.setValues({ id, status: undefined, zone_id: undefined, category_id: undefined });
|
||||
if (id > 0) {
|
||||
const row = data.values || { id };
|
||||
try {
|
||||
const info = await getDeliveryWarehouseProductInfo(id);
|
||||
detail.value = { ...row, ...(info || {}) };
|
||||
} catch {
|
||||
detail.value = row;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal title="仓品审核" class="w-[80%] md:w-[50%] lg:w-[40%]">
|
||||
<div v-if="detail" class="mb-4">
|
||||
<Descriptions :column="1" size="small" bordered>
|
||||
<Descriptions.Item label="药品名称">
|
||||
{{ detail.drug_name || '-' }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="规格">
|
||||
{{ detail.specification || '-' }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="类型">
|
||||
{{ detail.type_txt || '-' }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="上传报价">
|
||||
¥{{ detail.upload_quote || '0' }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="当前状态">
|
||||
<Tag>{{ detail.status_txt || '-' }}</Tag>
|
||||
<Tag color="orange" class="ml-1">
|
||||
{{ detail.audit_status_txt || '待审核' }}
|
||||
</Tag>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item v-if="detail.image" label="产品图">
|
||||
<Image :src="detail.image" :height="48" :width="48" />
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</div>
|
||||
<Form />
|
||||
</Modal>
|
||||
</template>
|
||||
@@ -0,0 +1,41 @@
|
||||
import type { VbenFormProps } from '#/adapter/form';
|
||||
|
||||
/**
|
||||
* 平台仓品审核搜索
|
||||
* audit_status 默认空字符串:后端按待审过滤;选「已审核」可看历史
|
||||
*/
|
||||
export const formOptions: VbenFormProps = {
|
||||
collapsed: false,
|
||||
schema: [
|
||||
{
|
||||
component: 'VbenInput',
|
||||
componentProps: {
|
||||
placeholder: '输入药品名称',
|
||||
allowClear: true,
|
||||
},
|
||||
fieldName: 'drug_name',
|
||||
label: '药品名称',
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
placeholder: '默认待审核',
|
||||
options: [
|
||||
// value 空串:后端 auditList 默认按待审过滤
|
||||
{ label: '待审核', value: '' },
|
||||
{ label: '已审核', value: 1 },
|
||||
],
|
||||
},
|
||||
defaultValue: '',
|
||||
fieldName: 'audit_status',
|
||||
label: '审核状态',
|
||||
},
|
||||
],
|
||||
showCollapseButton: true,
|
||||
submitButtonOptions: {
|
||||
content: '查询',
|
||||
},
|
||||
submitOnChange: true,
|
||||
submitOnEnter: false,
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||
|
||||
import { getDeliveryWarehouseProductAuditList } from '../api';
|
||||
|
||||
interface RowType {
|
||||
id: number;
|
||||
image?: string;
|
||||
drug_name: string;
|
||||
type_txt?: string;
|
||||
audit_status: number;
|
||||
audit_status_txt?: string;
|
||||
status: number;
|
||||
status_txt?: string;
|
||||
status_color?: string;
|
||||
uploader_name?: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 平台仓品审核表格
|
||||
*/
|
||||
export const gridOptions: VxeGridProps<RowType> = {
|
||||
checkboxConfig: {
|
||||
highlight: true,
|
||||
labelField: '',
|
||||
},
|
||||
columnConfig: {
|
||||
useKey: true,
|
||||
},
|
||||
rowConfig: {
|
||||
useKey: true,
|
||||
},
|
||||
columns: [
|
||||
{ field: 'id', align: 'left', title: 'ID', width: 80 },
|
||||
{
|
||||
field: 'image',
|
||||
title: '图片',
|
||||
width: 80,
|
||||
slots: { default: 'image' },
|
||||
},
|
||||
{ field: 'drug_name', title: '药品名称', minWidth: 160 },
|
||||
{ field: 'type_txt', title: '类型', width: 110 },
|
||||
{
|
||||
field: 'audit_status_txt',
|
||||
title: '审核状态',
|
||||
width: 110,
|
||||
slots: { default: 'audit_status' },
|
||||
},
|
||||
{
|
||||
field: 'status_txt',
|
||||
title: '商品状态',
|
||||
width: 100,
|
||||
slots: { default: 'status' },
|
||||
},
|
||||
{ field: 'uploader_name', title: '上传人', width: 120 },
|
||||
{ field: 'created_at', title: '创建时间', width: 170 },
|
||||
{
|
||||
type: 'html',
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
width: 120,
|
||||
slots: { default: 'action' },
|
||||
},
|
||||
],
|
||||
keepSource: true,
|
||||
pagerConfig: {},
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({ page }, formValues) => {
|
||||
return await getDeliveryWarehouseProductAuditList({
|
||||
page: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
...formValues,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
height: 'auto',
|
||||
border: false,
|
||||
toolbarConfig: {
|
||||
// @ts-ignore
|
||||
search: true,
|
||||
refresh: true,
|
||||
print: false,
|
||||
export: false,
|
||||
zoom: true,
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
},
|
||||
custom: {
|
||||
icon: 'vxe-icon-menu',
|
||||
},
|
||||
},
|
||||
showOverflow: false,
|
||||
};
|
||||
@@ -0,0 +1,127 @@
|
||||
<script lang="ts" setup>
|
||||
/**
|
||||
* 平台「仓品审核」列表页
|
||||
* 审核通过后自动打开仓药绑定弹窗,预填本仓+药品+报价
|
||||
*/
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { Image, Tag } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { TableAction } from '#/components/table-action';
|
||||
import BindModalDemo from '#/views/system/delivery-warehouse-drug/components/modal.vue';
|
||||
|
||||
import AuditModalDemo from './components/audit-modal.vue';
|
||||
import { formOptions } from './config/search';
|
||||
import { gridOptions } from './config/table';
|
||||
|
||||
defineOptions({ name: 'DeliveryWarehouseProductAudit' });
|
||||
|
||||
const [Grid, gridApi] = useVbenVxeGrid({
|
||||
formOptions,
|
||||
gridOptions,
|
||||
});
|
||||
|
||||
const [AuditModal, auditModalApi] = useVbenModal({
|
||||
connectedComponent: AuditModalDemo,
|
||||
});
|
||||
|
||||
const [BindModal, bindModalApi] = useVbenModal({
|
||||
connectedComponent: BindModalDemo,
|
||||
});
|
||||
|
||||
/**
|
||||
* 审核成功后打开仓药绑定:锁定药品、预填仓库与报价
|
||||
*/
|
||||
function openBindFromPreset(preset: Record<string, any>) {
|
||||
if (!preset?.drug_id || !preset?.warehouse_id) {
|
||||
return;
|
||||
}
|
||||
bindModalApi.setData({
|
||||
update: false,
|
||||
lockDrug: true,
|
||||
presetDrug: preset.presetDrug || {
|
||||
id: preset.drug_id,
|
||||
drug_name: preset.drug_name,
|
||||
specification: preset.specification,
|
||||
image: preset.image,
|
||||
},
|
||||
values: {
|
||||
warehouse_id: preset.warehouse_id,
|
||||
drug_id: preset.drug_id,
|
||||
quote: preset.quote,
|
||||
status: 2,
|
||||
},
|
||||
gridApi,
|
||||
});
|
||||
bindModalApi.open();
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开审核弹窗(仅待审可点)
|
||||
*/
|
||||
function openAudit(row: Record<string, any>) {
|
||||
if (Number(row.audit_status) === 1) {
|
||||
return;
|
||||
}
|
||||
auditModalApi.setData({
|
||||
id: row.id,
|
||||
values: row,
|
||||
gridApi,
|
||||
onBindPreset: openBindFromPreset,
|
||||
});
|
||||
auditModalApi.open();
|
||||
}
|
||||
|
||||
function auditTagColor(status: number) {
|
||||
return Number(status) === 1 ? 'green' : 'orange';
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page auto-content-height title="仓品审核">
|
||||
<AuditModal />
|
||||
<BindModal />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<TableAction :actions="[]" :drop-down-actions="[]" />
|
||||
</template>
|
||||
<template #image="{ row }">
|
||||
<Image
|
||||
v-if="row.image"
|
||||
:src="row.image"
|
||||
:height="36"
|
||||
:width="36"
|
||||
:preview="true"
|
||||
/>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
<template #audit_status="{ row }">
|
||||
<Tag :color="auditTagColor(row.audit_status)">
|
||||
{{ row.audit_status_txt || '-' }}
|
||||
</Tag>
|
||||
</template>
|
||||
<template #status="{ row }">
|
||||
<Tag :color="row.status_color || 'default'">
|
||||
{{ row.status_txt || '-' }}
|
||||
</Tag>
|
||||
</template>
|
||||
<template #toolbar-tools></template>
|
||||
<template #action="{ row }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
label: '审核',
|
||||
type: 'link',
|
||||
icon: 'mdi:clipboard-check-outline',
|
||||
size: 'small',
|
||||
ifShow: Number(row.audit_status) !== 1,
|
||||
onClick: openAudit.bind(null, row),
|
||||
},
|
||||
]"
|
||||
:drop-down-actions="[]"
|
||||
/>
|
||||
</template>
|
||||
</Grid>
|
||||
</Page>
|
||||
</template>
|
||||
@@ -0,0 +1,40 @@
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
const prefix = 'delivery-warehouse-product/';
|
||||
|
||||
/**
|
||||
* 仓侧「我的商品」分页列表
|
||||
* 为什么单独封装:列表 / 审核列表走不同接口,避免混用参数
|
||||
*/
|
||||
export async function getDeliveryWarehouseProductList(data: any) {
|
||||
return requestClient.get<any>(`${prefix}list`, { params: data });
|
||||
}
|
||||
|
||||
/**
|
||||
* 仓品详情(编辑回填 / 审核弹窗预览)
|
||||
*/
|
||||
export async function getDeliveryWarehouseProductInfo(id: number) {
|
||||
return requestClient.get<any>(`${prefix}detail`, { params: { id } });
|
||||
}
|
||||
|
||||
/**
|
||||
* 仓侧新建商品(后端强制草稿 + 待审)
|
||||
*/
|
||||
export async function createDeliveryWarehouseProduct(data: Record<string, any>) {
|
||||
return requestClient.post<any>(`${prefix}create`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 仓侧编辑商品
|
||||
* 未审核时后端会忽略 status;已审核才可改上下架
|
||||
*/
|
||||
export async function updateDeliveryWarehouseProduct(data: Record<string, any>) {
|
||||
return requestClient.post<any>(`${prefix}update`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 仓侧可选商品类型(已排除中药)
|
||||
*/
|
||||
export async function getDeliveryWarehouseProductTypeOptions() {
|
||||
return requestClient.get<any>(`${prefix}type-options`);
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<script lang="ts" setup>
|
||||
/**
|
||||
* 配送仓建品弹窗
|
||||
* 新建:不传 status(后端强制草稿);编辑:按 audit_status 控制 status 显隐
|
||||
* 用法字典复用西药 getDrugUseList,避免各品类重复维护
|
||||
*/
|
||||
import { nextTick, ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { getDrugUseList } from '#/views/doctor/doctor-reception/api';
|
||||
|
||||
import {
|
||||
createDeliveryWarehouseProduct,
|
||||
getDeliveryWarehouseProductInfo,
|
||||
updateDeliveryWarehouseProduct,
|
||||
} from '../api';
|
||||
import { modalFormProps } from '../config/form';
|
||||
|
||||
const isUpdate = ref(false);
|
||||
const gridApi = ref();
|
||||
const drugTime = ref<{ label: string; value: number }[]>([]);
|
||||
const drugType = ref<{ label: string; value: number }[]>([]);
|
||||
const drugUnit = ref<{ label: string; value: number }[]>([]);
|
||||
const drugFrequency = ref<{ label: string; value: number }[]>([]);
|
||||
|
||||
/** 预拉取用法字典,打开弹窗时注入 Select options */
|
||||
getDrugUseList().then((res) => {
|
||||
drugTime.value = (res.drug_time || []).map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
}));
|
||||
drugType.value = (res.drug_use_type || []).map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
}));
|
||||
drugUnit.value = (res.drug_unit || []).map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
}));
|
||||
drugFrequency.value = (res.drug_use_frequency || []).map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
}));
|
||||
});
|
||||
|
||||
const [Form, formApi] = useVbenForm(modalFormProps);
|
||||
|
||||
/** 把用法字典写入四个 Select,保证每次打开都有最新 options */
|
||||
function injectUseDictOptions() {
|
||||
formApi.updateSchema([
|
||||
{ fieldName: 'time_id', componentProps: { options: drugTime.value } },
|
||||
{ fieldName: 'unit_id', componentProps: { options: drugUnit.value } },
|
||||
{ fieldName: 'type_id', componentProps: { options: drugType.value } },
|
||||
{
|
||||
fieldName: 'frequency_id',
|
||||
componentProps: { options: drugFrequency.value },
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
fullscreenButton: false,
|
||||
draggable: true,
|
||||
onCancel() {
|
||||
modalApi.close();
|
||||
},
|
||||
onConfirm: async () => {
|
||||
formApi.validate().then(async (e: any) => {
|
||||
if (e.valid) {
|
||||
const values = await formApi.getValues();
|
||||
// 新建不提交 status;未审核编辑也不提交(后端也会忽略,前端再挡一层)
|
||||
const payload = { ...values };
|
||||
if (!isUpdate.value || Number(payload.audit_status) === 0) {
|
||||
delete payload.status;
|
||||
}
|
||||
delete payload.audit_status;
|
||||
modalApi.setState({ loading: true, confirmLoading: true });
|
||||
const submitApi = isUpdate.value
|
||||
? updateDeliveryWarehouseProduct
|
||||
: createDeliveryWarehouseProduct;
|
||||
submitApi(payload)
|
||||
.then(() => {
|
||||
message.success('保存成功');
|
||||
gridApi.value?.query?.() ?? gridApi.value?.reload?.();
|
||||
modalApi.close();
|
||||
})
|
||||
.finally(() => {
|
||||
modalApi.setState({ loading: false, confirmLoading: false });
|
||||
});
|
||||
}
|
||||
});
|
||||
await formApi.validateAndSubmitForm();
|
||||
},
|
||||
async onOpenChange(isOpen: boolean) {
|
||||
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
|
||||
if (!isOpen) {
|
||||
return;
|
||||
}
|
||||
injectUseDictOptions();
|
||||
await formApi.resetForm();
|
||||
const { values, update } = modalApi.getData<Record<string, any>>() || {};
|
||||
isUpdate.value = !!update;
|
||||
if (update && values?.id) {
|
||||
// 编辑拉详情;zone_id 联动会清空 category_id,需 nextTick 后补回
|
||||
try {
|
||||
const detail = await getDeliveryWarehouseProductInfo(values.id);
|
||||
const merged = {
|
||||
...values,
|
||||
...(detail || {}),
|
||||
introduction_images: detail?.introduction_images || [],
|
||||
};
|
||||
const categoryId = merged.category_id;
|
||||
await formApi.setValues(merged);
|
||||
await nextTick();
|
||||
if (categoryId) {
|
||||
await formApi.setFieldValue('category_id', categoryId);
|
||||
}
|
||||
} catch {
|
||||
await formApi.setValues(values || {});
|
||||
}
|
||||
} else if (values) {
|
||||
await formApi.setValues(values);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal
|
||||
:title="`${isUpdate === true ? '编辑' : '新增'}仓品`"
|
||||
class="w-[80%] md:w-[50%] lg:w-[40%] h-[70%]"
|
||||
>
|
||||
<Form />
|
||||
</Modal>
|
||||
</template>
|
||||
@@ -0,0 +1,239 @@
|
||||
import type { VbenFormProps } from '#/adapter/form';
|
||||
|
||||
import { getSupplierOption } from '#/views/system/supplier/api';
|
||||
|
||||
import { getDeliveryWarehouseProductTypeOptions } from '../api';
|
||||
|
||||
/**
|
||||
* 仓侧建品弹窗表单
|
||||
* 不填药品编号/ERP倍数/分区(后端默认);必填报价供审核绑仓
|
||||
*/
|
||||
export const modalFormProps: VbenFormProps = {
|
||||
wrapperClass: 'grid-cols-12',
|
||||
commonConfig: {
|
||||
formItemClass: 'col-span-12',
|
||||
componentProps: {
|
||||
class: 'w-full',
|
||||
},
|
||||
},
|
||||
layout: 'horizontal',
|
||||
schema: [
|
||||
{
|
||||
component: 'VbenInput',
|
||||
fieldName: 'id',
|
||||
label: 'ID',
|
||||
formItemClass: 'col-span-6',
|
||||
dependencies: {
|
||||
show: false,
|
||||
triggerFields: ['id'],
|
||||
},
|
||||
},
|
||||
{
|
||||
// 隐藏:驱动 status 显隐(audit_status==1 才可改上下架)
|
||||
component: 'VbenInput',
|
||||
fieldName: 'audit_status',
|
||||
label: '审核状态',
|
||||
formItemClass: 'col-span-6',
|
||||
dependencies: {
|
||||
show: false,
|
||||
triggerFields: ['audit_status'],
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
allowClear: false,
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any) =>
|
||||
option?.label?.toLowerCase?.().indexOf(input.toLowerCase()) >= 0,
|
||||
afterFetch: (data: { label: string; value: number }[]) =>
|
||||
(data || []).map((item) => ({
|
||||
label: item.label,
|
||||
value: item.value,
|
||||
})),
|
||||
api: getDeliveryWarehouseProductTypeOptions,
|
||||
placeholder: '请选择商品类型',
|
||||
},
|
||||
fieldName: 'type',
|
||||
formItemClass: 'col-span-6',
|
||||
label: '商品类型',
|
||||
rules: 'selectRequired',
|
||||
},
|
||||
{
|
||||
component: 'Avatar',
|
||||
fieldName: 'image',
|
||||
label: '产品图片',
|
||||
rules: 'required',
|
||||
formItemClass: 'col-span-6',
|
||||
},
|
||||
{
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any) =>
|
||||
option?.label?.toLowerCase?.().indexOf(input.toLowerCase()) >= 0,
|
||||
afterFetch: (data: { id: number; name: string }[]) =>
|
||||
(data || []).map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
})),
|
||||
api: getSupplierOption,
|
||||
placeholder: '请选择',
|
||||
},
|
||||
fieldName: 'supplier_id',
|
||||
formItemClass: 'col-span-6',
|
||||
label: '所属供应商',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
placeholder: '请输入报价',
|
||||
min: 0.0001,
|
||||
precision: 4,
|
||||
class: 'w-full',
|
||||
},
|
||||
fieldName: 'upload_quote',
|
||||
formItemClass: 'col-span-6',
|
||||
label: '报价',
|
||||
help: '审核通过后将按此报价绑定到本配送仓',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'VbenInput',
|
||||
componentProps: {
|
||||
placeholder: '请输入药品昵称',
|
||||
},
|
||||
fieldName: 'drug_name',
|
||||
formItemClass: 'col-span-6',
|
||||
label: '药品昵称',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'VbenInput',
|
||||
componentProps: {
|
||||
placeholder: '请输入药品别名',
|
||||
},
|
||||
fieldName: 'drug_alias',
|
||||
formItemClass: 'col-span-6',
|
||||
label: '药品别名',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'VbenInput',
|
||||
componentProps: {
|
||||
placeholder: '请输入规格',
|
||||
},
|
||||
fieldName: 'specification',
|
||||
formItemClass: 'col-span-6',
|
||||
label: '规格',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'VbenSelect',
|
||||
componentProps: {
|
||||
options: [],
|
||||
placeholder: '请选择',
|
||||
},
|
||||
fieldName: 'time_id',
|
||||
formItemClass: 'col-span-6',
|
||||
label: '使用时间',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'VbenSelect',
|
||||
componentProps: {
|
||||
options: [],
|
||||
placeholder: '请选择',
|
||||
},
|
||||
fieldName: 'type_id',
|
||||
formItemClass: 'col-span-6',
|
||||
label: '使用方法',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'VbenSelect',
|
||||
componentProps: {
|
||||
options: [],
|
||||
placeholder: '请选择',
|
||||
},
|
||||
fieldName: 'unit_id',
|
||||
formItemClass: 'col-span-6',
|
||||
label: '单位',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'VbenSelect',
|
||||
componentProps: {
|
||||
options: [],
|
||||
placeholder: '请选择',
|
||||
},
|
||||
fieldName: 'frequency_id',
|
||||
formItemClass: 'col-span-6',
|
||||
label: '频率',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
// 新建不展示;未审核(audit_status==0)不展示;已审核可选草稿/下架/上架
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '草稿', value: 1 },
|
||||
{ label: '下架', value: 2 },
|
||||
{ label: '上架', value: 3 },
|
||||
],
|
||||
},
|
||||
fieldName: 'status',
|
||||
formItemClass: 'col-span-12',
|
||||
label: '商品状态',
|
||||
dependencies: {
|
||||
show(values) {
|
||||
return !!values?.id && Number(values?.audit_status) === 1;
|
||||
},
|
||||
triggerFields: ['id', 'audit_status'],
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'RadioGroup',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '是', value: 0 },
|
||||
{ label: '否', value: 1 },
|
||||
],
|
||||
},
|
||||
defaultValue: 1,
|
||||
formItemClass: 'col-span-12',
|
||||
fieldName: 'is_otc',
|
||||
label: '是否处方药',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'Textarea',
|
||||
componentProps: {
|
||||
placeholder: '请输入药品主治功能',
|
||||
},
|
||||
fieldName: 'function',
|
||||
label: '药品主治功能',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'Avatar',
|
||||
fieldName: 'instruction',
|
||||
label: '产品说明书',
|
||||
rules: 'required',
|
||||
formItemClass: 'col-span-6',
|
||||
},
|
||||
{
|
||||
component: 'UploadImageSortable',
|
||||
fieldName: 'introduction_images',
|
||||
label: '商品介绍图',
|
||||
formItemClass: 'col-span-12',
|
||||
componentProps: {
|
||||
maxCount: 20,
|
||||
multiple: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
showDefaultActions: false,
|
||||
};
|
||||
@@ -0,0 +1,74 @@
|
||||
import type { VbenFormProps } from '#/adapter/form';
|
||||
|
||||
import { getDeliveryWarehouseProductTypeOptions } from '../api';
|
||||
|
||||
/**
|
||||
* 仓侧「我的商品」顶部搜索
|
||||
* 字段与后端 queryField 对齐:名称模糊、类型/审核/状态精确
|
||||
*/
|
||||
export const formOptions: VbenFormProps = {
|
||||
collapsed: false,
|
||||
schema: [
|
||||
{
|
||||
component: 'VbenInput',
|
||||
componentProps: {
|
||||
placeholder: '输入药品名称',
|
||||
allowClear: true,
|
||||
},
|
||||
fieldName: 'drug_name',
|
||||
label: '药品名称',
|
||||
},
|
||||
{
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any) =>
|
||||
option?.label?.toLowerCase?.().indexOf(input.toLowerCase()) >= 0,
|
||||
// type-options 已是 { label, value }
|
||||
afterFetch: (data: { label: string; value: number }[]) =>
|
||||
(data || []).map((item) => ({
|
||||
label: item.label,
|
||||
value: item.value,
|
||||
})),
|
||||
api: getDeliveryWarehouseProductTypeOptions,
|
||||
placeholder: '请选择类型',
|
||||
},
|
||||
fieldName: 'type',
|
||||
label: '商品类型',
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
placeholder: '请选择审核状态',
|
||||
options: [
|
||||
{ label: '待审核', value: 0 },
|
||||
{ label: '已审核', value: 1 },
|
||||
],
|
||||
},
|
||||
fieldName: 'audit_status',
|
||||
label: '审核状态',
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
placeholder: '请选择商品状态',
|
||||
options: [
|
||||
{ label: '草稿', value: 1 },
|
||||
{ label: '下架', value: 2 },
|
||||
{ label: '上架', value: 3 },
|
||||
],
|
||||
},
|
||||
fieldName: 'status',
|
||||
label: '商品状态',
|
||||
},
|
||||
],
|
||||
showCollapseButton: true,
|
||||
submitButtonOptions: {
|
||||
content: '查询',
|
||||
},
|
||||
submitOnChange: true,
|
||||
submitOnEnter: false,
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||
|
||||
import { getDeliveryWarehouseProductList } from '../api';
|
||||
|
||||
interface RowType {
|
||||
id: number;
|
||||
image?: string;
|
||||
drug_name: string;
|
||||
type_txt?: string;
|
||||
audit_status: number;
|
||||
audit_status_txt?: string;
|
||||
status: number;
|
||||
status_txt?: string;
|
||||
status_color?: string;
|
||||
uploader_name?: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 仓侧「我的商品」表格列与远程分页
|
||||
*/
|
||||
export const gridOptions: VxeGridProps<RowType> = {
|
||||
checkboxConfig: {
|
||||
highlight: true,
|
||||
labelField: '',
|
||||
},
|
||||
columnConfig: {
|
||||
useKey: true,
|
||||
},
|
||||
rowConfig: {
|
||||
useKey: true,
|
||||
},
|
||||
columns: [
|
||||
{ field: 'id', align: 'left', title: 'ID', width: 80 },
|
||||
{
|
||||
field: 'image',
|
||||
title: '图片',
|
||||
width: 80,
|
||||
slots: { default: 'image' },
|
||||
},
|
||||
{ field: 'drug_name', title: '药品名称', minWidth: 160 },
|
||||
{ field: 'type_txt', title: '类型', width: 110 },
|
||||
{
|
||||
field: 'audit_status_txt',
|
||||
title: '审核状态',
|
||||
width: 110,
|
||||
slots: { default: 'audit_status' },
|
||||
},
|
||||
{
|
||||
field: 'status_txt',
|
||||
title: '商品状态',
|
||||
width: 100,
|
||||
slots: { default: 'status' },
|
||||
},
|
||||
{ field: 'uploader_name', title: '上传人', width: 120 },
|
||||
{ field: 'created_at', title: '创建时间', width: 170 },
|
||||
{
|
||||
type: 'html',
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
width: 120,
|
||||
slots: { default: 'action' },
|
||||
},
|
||||
],
|
||||
keepSource: true,
|
||||
pagerConfig: {},
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({ page }, formValues) => {
|
||||
return await getDeliveryWarehouseProductList({
|
||||
page: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
...formValues,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
height: 'auto',
|
||||
border: false,
|
||||
toolbarConfig: {
|
||||
// @ts-ignore
|
||||
search: true,
|
||||
refresh: true,
|
||||
print: false,
|
||||
export: false,
|
||||
zoom: true,
|
||||
slots: {
|
||||
buttons: 'toolbar-buttons',
|
||||
},
|
||||
custom: {
|
||||
icon: 'vxe-icon-menu',
|
||||
},
|
||||
},
|
||||
showOverflow: false,
|
||||
};
|
||||
@@ -0,0 +1,102 @@
|
||||
<script lang="ts" setup>
|
||||
/**
|
||||
* 配送仓「我的商品」列表页
|
||||
* 仓侧建品与上下架入口;未审核商品无专用上下架按钮(仅编辑)
|
||||
*/
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { Image, Tag } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { TableAction } from '#/components/table-action';
|
||||
|
||||
import FormModalDemo from './components/modal.vue';
|
||||
import { formOptions } from './config/search';
|
||||
import { gridOptions } from './config/table';
|
||||
|
||||
defineOptions({ name: 'DeliveryWarehouseProduct' });
|
||||
|
||||
const [Grid, gridApi] = useVbenVxeGrid({
|
||||
formOptions,
|
||||
gridOptions,
|
||||
});
|
||||
|
||||
const [FormModal, formModalApi] = useVbenModal({
|
||||
connectedComponent: FormModalDemo,
|
||||
});
|
||||
|
||||
/**
|
||||
* 打开新建/编辑弹窗
|
||||
* @param data 行数据;新建传空对象
|
||||
* @param isUpdate 是否编辑
|
||||
*/
|
||||
const showModal = (data: Record<string, any> = {}, isUpdate = false) => {
|
||||
formModalApi.setData({
|
||||
values: data,
|
||||
update: isUpdate,
|
||||
gridApi,
|
||||
});
|
||||
formModalApi.open();
|
||||
};
|
||||
|
||||
/** 审核状态 Tag 颜色:待审橙、已审绿 */
|
||||
function auditTagColor(status: number) {
|
||||
return Number(status) === 1 ? 'green' : 'orange';
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page auto-content-height title="我的商品">
|
||||
<FormModal />
|
||||
<Grid>
|
||||
<template #toolbar-buttons>
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
label: '新增',
|
||||
type: 'primary',
|
||||
icon: 'ant-design:plus-outlined',
|
||||
onClick: showModal.bind(null),
|
||||
},
|
||||
]"
|
||||
:drop-down-actions="[]"
|
||||
/>
|
||||
</template>
|
||||
<template #image="{ row }">
|
||||
<Image
|
||||
v-if="row.image"
|
||||
:src="row.image"
|
||||
:height="36"
|
||||
:width="36"
|
||||
:preview="true"
|
||||
/>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
<template #audit_status="{ row }">
|
||||
<Tag :color="auditTagColor(row.audit_status)">
|
||||
{{ row.audit_status_txt || '-' }}
|
||||
</Tag>
|
||||
</template>
|
||||
<template #status="{ row }">
|
||||
<Tag :color="row.status_color || 'default'">
|
||||
{{ row.status_txt || '-' }}
|
||||
</Tag>
|
||||
</template>
|
||||
<template #toolbar-tools></template>
|
||||
<template #action="{ row }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
label: '编辑',
|
||||
type: 'link',
|
||||
icon: 'uil:edit',
|
||||
size: 'small',
|
||||
onClick: showModal.bind(null, row, true),
|
||||
},
|
||||
]"
|
||||
:drop-down-actions="[]"
|
||||
/>
|
||||
</template>
|
||||
</Grid>
|
||||
</Page>
|
||||
</template>
|
||||
@@ -5,6 +5,7 @@ import { useVbenDrawer } from '@vben/common-ui';
|
||||
|
||||
import { Button, Descriptions, Image, Spin } from 'ant-design-vue';
|
||||
|
||||
import FilePreviewModal from '#/components/file-preview/FilePreviewModal.vue';
|
||||
import MIcon from '#/components/icon/icon.vue';
|
||||
import { XgVideoPlayer } from '#/components/video-player';
|
||||
import type { FileGalleryDetail } from '#/api/core/file-gallery';
|
||||
@@ -14,6 +15,8 @@ defineOptions({ name: 'FileDetailDrawer' });
|
||||
|
||||
const loading = ref(false);
|
||||
const detail = ref<FileGalleryDetail | null>(null);
|
||||
const previewOpen = ref(false);
|
||||
const previewFiles = ref<string[]>([]);
|
||||
|
||||
const [Drawer, drawerApi] = useVbenDrawer({
|
||||
class: 'w-[520px]',
|
||||
@@ -45,6 +48,15 @@ function downloadFile() {
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
|
||||
/** 图片/PDF 走公共预览组件 */
|
||||
function openPreview() {
|
||||
if (!detail.value?.url) {
|
||||
return;
|
||||
}
|
||||
previewFiles.value = [detail.value.url];
|
||||
previewOpen.value = true;
|
||||
}
|
||||
|
||||
async function loadDetail() {
|
||||
const data = drawerApi.getData<{ id?: number }>();
|
||||
if (!data?.id) {
|
||||
@@ -67,10 +79,11 @@ defineExpose({
|
||||
|
||||
<template>
|
||||
<Drawer title="文件详情">
|
||||
<FilePreviewModal v-model:open="previewOpen" :files="previewFiles" title="素材预览" />
|
||||
<Spin :spinning="loading">
|
||||
<template v-if="detail">
|
||||
<div class="preview-wrap">
|
||||
<Image v-if="detail.type === 0" :src="detail.url" :width="220" />
|
||||
<Image v-if="detail.type === 0" :src="detail.url" :width="220" :preview="true" />
|
||||
<XgVideoPlayer
|
||||
v-else-if="detail.type === 1"
|
||||
:src="detail.url"
|
||||
@@ -84,7 +97,10 @@ defineExpose({
|
||||
/>
|
||||
<div v-else-if="detail.type === 5" class="fallback-preview">
|
||||
<MIcon v-if="detail.type_icon" :icon="detail.type_icon" size="48" />
|
||||
<Button type="primary" @click="downloadFile">下载 PDF</Button>
|
||||
<div class="btn-row">
|
||||
<Button type="primary" @click="openPreview">预览 PDF</Button>
|
||||
<Button @click="downloadFile">下载 PDF</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="fallback-preview">
|
||||
<MIcon v-if="detail.type_icon" :icon="detail.type_icon" size="48" />
|
||||
@@ -138,11 +154,22 @@ defineExpose({
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 24px;
|
||||
width: 100%;
|
||||
border-radius: 8px;
|
||||
border: 1px solid hsl(var(--border));
|
||||
background: hsl(var(--muted) / 0.25);
|
||||
color: hsl(var(--foreground));
|
||||
}
|
||||
|
||||
.btn-row {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.type-row {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
color: hsl(var(--foreground));
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -357,8 +357,7 @@ watch(typesLoading, (val) => {
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use '#/components/form/components/picker-card-theme.scss' as theme;
|
||||
|
||||
/* 素材库卡片:用主题变量适配明/暗色,避免硬编码浅色底 */
|
||||
.tab-label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -387,9 +386,10 @@ watch(typesLoading, (val) => {
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 10px;
|
||||
border: 1px solid #e5e6eb;
|
||||
border: 1px solid hsl(var(--border));
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
background: hsl(var(--card));
|
||||
color: hsl(var(--card-foreground));
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ watch(typesLoading, (val) => {
|
||||
height: 120px;
|
||||
object-fit: cover;
|
||||
border-radius: 6px;
|
||||
background: #f5f5f5;
|
||||
background: hsl(var(--muted) / 0.45);
|
||||
}
|
||||
|
||||
.gallery-file-icon {
|
||||
@@ -409,8 +409,8 @@ watch(typesLoading, (val) => {
|
||||
gap: 8px;
|
||||
height: 120px;
|
||||
border-radius: 6px;
|
||||
background: #f5f5f5;
|
||||
color: #4e5969;
|
||||
background: hsl(var(--muted) / 0.45);
|
||||
color: hsl(var(--muted-foreground));
|
||||
padding: 8px;
|
||||
|
||||
.file-name {
|
||||
@@ -425,7 +425,7 @@ watch(typesLoading, (val) => {
|
||||
|
||||
.gallery-meta {
|
||||
font-size: 12px;
|
||||
color: #86909c;
|
||||
color: hsl(var(--muted-foreground));
|
||||
text-align: center;
|
||||
|
||||
.file-title {
|
||||
@@ -433,7 +433,7 @@ watch(typesLoading, (val) => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
color: #1d2129;
|
||||
color: hsl(var(--foreground));
|
||||
font-weight: 500;
|
||||
margin-bottom: 4px;
|
||||
max-width: 100%;
|
||||
@@ -452,23 +452,4 @@ watch(typesLoading, (val) => {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dark {
|
||||
.gallery-card {
|
||||
@include theme.picker-card-dark-props;
|
||||
}
|
||||
|
||||
.gallery-thumb,
|
||||
.gallery-file-icon {
|
||||
background: #374151;
|
||||
}
|
||||
|
||||
.gallery-meta {
|
||||
@include theme.picker-text-secondary-dark;
|
||||
|
||||
.file-title {
|
||||
color: #e5e7eb;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user