647 lines
20 KiB
Vue
647 lines
20 KiB
Vue
<template>
|
||
<div v-can="permissionCodes.salesOrder.create" class="sales-order-create">
|
||
<t-form class="form" label-align="left" label-width="5.25rem" v-entrance-transition>
|
||
<t-form-item label="客户" required-mark>
|
||
<t-input
|
||
:model-value="customerDisplayText"
|
||
class="customer"
|
||
readonly
|
||
borderless
|
||
placeholder="选择或扫码客户"
|
||
@click="customerSelectorVisible = true"
|
||
>
|
||
<template #suffix-icon>
|
||
<div class="actions">
|
||
<t-button
|
||
theme="primary"
|
||
variant="outline"
|
||
size="extra-small"
|
||
@click.stop="customerSelectorVisible = true"
|
||
>选择</t-button>
|
||
<t-button theme="primary" size="extra-small" @click.stop="toggleScanner">
|
||
<span v-text="scannerVisible ? '关闭扫码' : '扫码'" />
|
||
</t-button>
|
||
</div>
|
||
</template>
|
||
</t-input>
|
||
</t-form-item>
|
||
<div v-if="scannerVisible" class="code-scanner-wrapper">
|
||
<code-scanner
|
||
visible
|
||
:status-text="scanStatus"
|
||
active-text="正在识别客户编码,请将条码或二维码移入取景框。"
|
||
@decode="handleDecodedText"
|
||
@status-change="handleScanStatusChange"
|
||
/>
|
||
</div>
|
||
<customer-profile-card
|
||
v-if="customer"
|
||
class="customer-profile"
|
||
:customer="customer"
|
||
v-entrance-transition
|
||
/>
|
||
<t-form-item label-width="0">
|
||
<div class="product-part">
|
||
<div class="header">
|
||
<strong>购买产品</strong>
|
||
<span v-text="`${items.length} 项`" />
|
||
</div>
|
||
<div class="tips">同一产品单位不能重复,数量最多三位小数</div>
|
||
<div class="items">
|
||
<div v-for="(item, index) in items" :key="item.clientKey" class="item">
|
||
<div class="header">
|
||
<span class="no" v-text="String(index + 1).padStart(2, '0')" />
|
||
<strong v-text="item.productName || '未选择产品'" />
|
||
<t-button theme="danger" variant="text" size="extra-small" @click="removeItem(index)">删除</t-button>
|
||
</div>
|
||
<product-selector
|
||
:model-value="item.productId ? {productId: item.productId, productUnitId: item.productUnitId || ''} : undefined"
|
||
label="产品"
|
||
placeholder="请选择产品"
|
||
selection-mode="product"
|
||
required-mark
|
||
@update:model-value="applyProduct(index, $event)"
|
||
/>
|
||
<t-form-item v-if="item.productId" label="产品单位" required-mark>
|
||
<div v-if="getSaleableUnits(item).length" class="unit-list">
|
||
<t-button
|
||
v-for="unit in getSaleableUnits(item)"
|
||
:key="unit.id"
|
||
:theme="item.productUnitId === unit.id ? 'primary' : 'default'"
|
||
:variant="item.productUnitId === unit.id ? 'base' : 'outline'"
|
||
size="extra-small"
|
||
:content="unit.name"
|
||
@click="selectProductUnit(index, unit)"
|
||
/>
|
||
</div>
|
||
<span v-else class="unit-empty" v-text="'暂无可售单位'" />
|
||
</t-form-item>
|
||
<t-form-item v-if="canPriceOverride" label="成交单价">
|
||
<t-input
|
||
v-model.trim="item.unitPriceText"
|
||
type="number"
|
||
align="right"
|
||
borderless
|
||
:placeholder="getItemUnitPricePlaceholder(item)"
|
||
/>
|
||
</t-form-item>
|
||
<t-form-item label="数量" content-align="right">
|
||
<t-stepper
|
||
v-model="item.quantity"
|
||
size="large"
|
||
:max="maxQuantity"
|
||
:min="getQuantityStep(item)"
|
||
:step="getQuantityStep(item)"
|
||
:integer="!getProduct(item)?.allowDecimalQuantity"
|
||
theme="outline"
|
||
/>
|
||
</t-form-item>
|
||
<t-form-item label="产品备注">
|
||
<t-input v-model.trim="item.remark" borderless placeholder="选填" />
|
||
</t-form-item>
|
||
<div class="price">
|
||
<strong class="coin red">¥</strong>
|
||
<strong class="value red" v-text="getItemSubtotalText(item)" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<t-button
|
||
class="add"
|
||
type="button"
|
||
theme="light"
|
||
variant="dashed"
|
||
block
|
||
@click="addItem"
|
||
>
|
||
<template #icon>
|
||
<t-icon name="add" size="1.125rem" />
|
||
</template>
|
||
<span>继续添加产品</span>
|
||
</t-button>
|
||
</div>
|
||
</t-form-item>
|
||
<t-form-item label="下单时间" content-align="right">
|
||
<div class="time-actions">
|
||
<t-button
|
||
theme="primary"
|
||
variant="outline"
|
||
size="extra-small"
|
||
:content="purchasedAtText || '此刻'"
|
||
@click="openTimePicker"
|
||
/>
|
||
<t-button
|
||
v-if="purchasedAtText"
|
||
theme="primary"
|
||
variant="text"
|
||
size="extra-small"
|
||
content="此刻"
|
||
@click="resetPurchasedAt"
|
||
/>
|
||
</div>
|
||
</t-form-item>
|
||
<t-form-item label="订单备注">
|
||
<t-textarea v-model.trim="remark" class="textarea" borderless autosize maxlength="500" placeholder="记录本单需要注意的内容" />
|
||
</t-form-item>
|
||
<div class="photo-part">
|
||
<photo-scroller :model-value="photoUrlList" v-model:photo-items="photoItems" :upload="uploadPhotoList" :edit-mode="true" title="订单照片(选填)" />
|
||
</div>
|
||
</t-form>
|
||
<div class="submit-wrap glass-white bg-white">
|
||
<div class="total">
|
||
<span>订单总价</span>
|
||
<div class="price">
|
||
<strong class="red coin">¥</strong>
|
||
<strong class="red value" v-text="totalAmountText" />
|
||
</div>
|
||
</div>
|
||
<t-button
|
||
class="submit"
|
||
theme="danger"
|
||
:loading="isSaving"
|
||
:disabled="isSaving"
|
||
@click="save"
|
||
>提交订单</t-button>
|
||
</div>
|
||
<customer-selector v-model="customerIdList" v-model:visible="customerSelectorVisible" selection-mode="single" @change="loadCustomer" />
|
||
<t-popup v-model="pickerVisible" placement="bottom">
|
||
<t-date-time-picker v-if="pickerVisible" v-model="draftTime" format="YYYY-MM-DD HH:mm" :mode="['date', 'minute']" title="下单时间" @cancel="pickerVisible = false" @confirm="confirmTime" />
|
||
</t-popup>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { type Attachment, useUserStore } from "timi-web-api";
|
||
import { Time } from "timi-web";
|
||
import CustomerAPI from "@/api/CustomerAPI";
|
||
import ProductAPI from "@/api/ProductAPI";
|
||
import SalesOrderAPI from "@/api/SalesOrderAPI";
|
||
import CodeScanner from "@/components/CodeScanner.vue";
|
||
import CustomerProfileCard from "@/components/CustomerProfileCard.vue";
|
||
import CustomerSelector from "@/components/CustomerSelector.vue";
|
||
import PhotoScroller from "@/components/PhotoScroller.vue";
|
||
import type { Customer } from "@/types/Customer";
|
||
import type { Product, ProductUnit } from "@/types/Product";
|
||
import type { PhotoItem } from "@/types/Photo";
|
||
import type { DirectProductOrderItemRequest } from "@/types/SalesOrder";
|
||
import { createPackageRequestNo, normalizePackageQuantity, parsePackageAmount } from "@/utils/package";
|
||
import { formatProductAmount, getProductQuantityStep } from "@/utils/product";
|
||
import { getErrorMessage } from "@/utils/error";
|
||
import { Message } from "@/utils/message";
|
||
import { permissionCodes } from "@/utils/permission";
|
||
import { uploadPhotoList } from "@/utils/photo";
|
||
import { useNavBarStore } from "@/store/navBarStore";
|
||
import { useSettingStore } from "@/store/settingStore";
|
||
|
||
type FormItem = Partial<DirectProductOrderItemRequest> & { clientKey: string; productName: string; unitPriceText: string };
|
||
defineOptions({ name: "SalesOrderCreate" });
|
||
const router = useRouter();
|
||
const navBarStore = useNavBarStore();
|
||
const settingStore = useSettingStore();
|
||
const userStore = useUserStore();
|
||
const canPriceOverride = computed(() => userStore.hasPermissions(permissionCodes.salesOrder.priceOverride));
|
||
const customerIdList = ref<string[]>([]);
|
||
const customer = ref<Customer>();
|
||
const customerSelectorVisible = ref(false);
|
||
const items = ref<FormItem[]>([]);
|
||
const remark = ref("");
|
||
const purchasedAtText = ref("");
|
||
const draftTime = ref("");
|
||
const pickerVisible = ref(false);
|
||
const isSaving = ref(false);
|
||
const photoItems = ref<PhotoItem[]>([]);
|
||
const photoUrlList = computed(() => photoItems.value.map(item => item.url));
|
||
const maxQuantity = Number.MAX_SAFE_INTEGER;
|
||
const productCache = new Map<string, Product>();
|
||
const requestNo = ref("");
|
||
const customerDisplayText = computed(() => customer.value?.name || customer.value?.code || "选择客户");
|
||
const customerCode = ref("");
|
||
const scanCode = ref("");
|
||
const scannerVisible = ref(false);
|
||
const scanStatus = ref("点击扫码开始识别。");
|
||
let latestDecodedText = "";
|
||
|
||
function getProduct(item: FormItem): Product | undefined {
|
||
return productCache.get(item.productId || "");
|
||
}
|
||
|
||
function getQuantityStep(item: FormItem): number {
|
||
return getProductQuantityStep(getProduct(item));
|
||
}
|
||
|
||
const totalAmount = computed(() => {
|
||
let amount = 0;
|
||
for (const item of items.value) {
|
||
const itemAmount = calculateItemAmount(item);
|
||
if (itemAmount === undefined) {
|
||
return undefined;
|
||
}
|
||
amount += itemAmount;
|
||
}
|
||
return amount;
|
||
});
|
||
const totalAmountText = computed(() => totalAmount.value === undefined ? "0.00" : formatProductAmount(totalAmount.value));
|
||
|
||
function createItem(): FormItem {
|
||
return {
|
||
clientKey: window.crypto.randomUUID(),
|
||
quantity: "1",
|
||
productName: "",
|
||
unitPriceText: "",
|
||
remark: ""
|
||
};
|
||
}
|
||
|
||
function addItem(): void {
|
||
items.value.push(createItem());
|
||
}
|
||
|
||
function removeItem(index: number): void {
|
||
if (1 < items.value.length) {
|
||
items.value.splice(index, 1);
|
||
} else {
|
||
Message.warning("订单至少需要一项产品");
|
||
}
|
||
}
|
||
|
||
async function applyProduct(index: number, value?: { productId: string; productUnitId: string }): Promise<void> {
|
||
if (!value) return;
|
||
const product = productCache.get(value.productId) || await ProductAPI.detail(value.productId);
|
||
productCache.set(value.productId, product);
|
||
const item = items.value[index];
|
||
const saleableUnits = (product.unitList || []).filter(unit => unit.allowSale !== false && unit.id);
|
||
const productUnitId = saleableUnits.length < 2 ? saleableUnits[0]?.id || "" : value.productUnitId;
|
||
const selectionChanged = item.productId !== value.productId || item.productUnitId !== productUnitId;
|
||
item.productId = value.productId;
|
||
item.productUnitId = productUnitId;
|
||
item.productName = product.name;
|
||
if (selectionChanged) {
|
||
item.unitPriceText = "";
|
||
}
|
||
}
|
||
function getSaleableUnits(item: FormItem): ProductUnit[] {
|
||
return (productCache.get(item.productId || "")?.unitList || []).filter(unit => unit.allowSale !== false && unit.id);
|
||
}
|
||
function selectProductUnit(index: number, unit: ProductUnit): void {
|
||
const item = items.value[index];
|
||
const product = productCache.get(item.productId || "");
|
||
if (!product?.id || !unit.id) {
|
||
return;
|
||
}
|
||
if (item.productUnitId !== unit.id) {
|
||
item.unitPriceText = "";
|
||
}
|
||
item.productUnitId = unit.id;
|
||
item.productName = product.name;
|
||
}
|
||
function getItemUnitPrice(item: FormItem): number | undefined {
|
||
if (canPriceOverride.value && item.unitPriceText.trim()) {
|
||
return parsePackageAmount(item.unitPriceText);
|
||
}
|
||
const salePrice = productCache.get(item.productId || "")?.unitList?.find(unit => unit.id === item.productUnitId)?.salePrice;
|
||
return salePrice === null ? undefined : salePrice;
|
||
}
|
||
function getItemUnitPricePlaceholder(item: FormItem): string {
|
||
const salePrice = productCache.get(item.productId || "")?.unitList?.find(unit => unit.id === item.productUnitId)?.salePrice;
|
||
return salePrice === undefined || salePrice === null ? "产品价" : `产品价:${formatProductAmount(salePrice)}`;
|
||
}
|
||
function calculateItemAmount(item: FormItem): number | undefined {
|
||
const quantity = normalizePackageQuantity(item.quantity ?? "");
|
||
const unitPrice = getItemUnitPrice(item);
|
||
if (!quantity || quantity === "0" || unitPrice === undefined) {
|
||
return undefined;
|
||
}
|
||
const [integerPart, fractionPart = ""] = quantity.split(".");
|
||
const quantityScale = 10n ** BigInt(fractionPart.length);
|
||
const quantityValue = BigInt(`${integerPart}${fractionPart}`);
|
||
const amount = BigInt(unitPrice) * quantityValue;
|
||
if (amount % quantityScale !== 0n) {
|
||
return undefined;
|
||
}
|
||
const result = Number(amount / quantityScale);
|
||
return Number.isSafeInteger(result) ? result : undefined;
|
||
}
|
||
function getItemSubtotalText(item: FormItem): string {
|
||
const amount = calculateItemAmount(item);
|
||
return amount === undefined ? "0.00" : formatProductAmount(amount);
|
||
}
|
||
async function loadCustomer(value: string | string[]): Promise<void> {
|
||
const id = Array.isArray(value) ? value[0] : value;
|
||
customer.value = id ? await CustomerAPI.detail(id) : undefined;
|
||
customerCode.value = customer.value?.code || "";
|
||
scanCode.value = customerCode.value;
|
||
}
|
||
function toggleScanner(): void {
|
||
scannerVisible.value = !scannerVisible.value;
|
||
if (scannerVisible.value) {
|
||
latestDecodedText = "";
|
||
}
|
||
}
|
||
async function handleDecodedText(rawText: string): Promise<void> {
|
||
const normalizedText = rawText.trim();
|
||
if (!normalizedText || normalizedText === latestDecodedText) {
|
||
return;
|
||
}
|
||
|
||
latestDecodedText = normalizedText;
|
||
scanCode.value = normalizedText;
|
||
await settingStore.playScanSuccessSound();
|
||
await applyScanCode();
|
||
}
|
||
async function applyScanCode(): Promise<void> {
|
||
customerCode.value = scanCode.value.trim();
|
||
scanStatus.value = `已识别 ${customerCode.value},正在加载客户档案。`;
|
||
if (!customerCode.value) {
|
||
return;
|
||
}
|
||
|
||
const result = await CustomerAPI.findByCode(customerCode.value);
|
||
if (!result?.id) {
|
||
customer.value = undefined;
|
||
customerIdList.value = [];
|
||
scanStatus.value = `客户 ${customerCode.value} 不存在,请先建档。`;
|
||
return;
|
||
}
|
||
|
||
customer.value = result;
|
||
customerIdList.value = [result.id];
|
||
scanStatus.value = `已识别 ${result.code || customerCode.value},已自动选中 ${result.name || "未命名客户"}。`;
|
||
scannerVisible.value = false;
|
||
}
|
||
function handleScanStatusChange(value: string): void {
|
||
scanStatus.value = value;
|
||
}
|
||
function openTimePicker(): void { draftTime.value = purchasedAtText.value || Time.formatDateTime(new Date()); pickerVisible.value = true; }
|
||
function confirmTime(value?: string | number): void { purchasedAtText.value = String(value || draftTime.value); pickerVisible.value = false; }
|
||
function resetPurchasedAt(): void { purchasedAtText.value = ""; draftTime.value = ""; }
|
||
function resolveTimestamp(value: string): number | undefined {
|
||
if (!value) return undefined;
|
||
const timestamp = new Date(value.replace(" ", "T")).getTime();
|
||
return Number.isFinite(timestamp) ? timestamp : undefined;
|
||
}
|
||
function buildAttachments(): Partial<Attachment>[] {
|
||
return photoItems.value.flatMap(item => item.tempFileId ? [{ tempFileId: item.tempFileId, attachType: "PHOTO" }] : []);
|
||
}
|
||
function validate(): boolean {
|
||
if (!customer.value?.id) { Message.warning("请选择客户"); return false; }
|
||
if (!items.value.length) { Message.warning("请至少添加一项产品"); return false; }
|
||
const keys = new Set<string>();
|
||
for (const item of items.value) {
|
||
const quantity = normalizePackageQuantity(item.quantity ?? "");
|
||
const key = `${item.productId}\u0000${item.productUnitId}`;
|
||
if (!item.productId || !item.productUnitId || !quantity || quantity === "0") { Message.warning("产品单位和正数量不能为空"); return false; }
|
||
if (getProduct(item) && !getProduct(item)!.allowDecimalQuantity && quantity.includes(".")) { Message.warning("该产品不允许小数数量"); return false; }
|
||
if (keys.has(key)) { Message.warning("产品单位不能重复"); return false; }
|
||
keys.add(key);
|
||
if (canPriceOverride.value && item.unitPriceText && parsePackageAmount(item.unitPriceText) === undefined) { Message.warning("成交单价必须是合法金额"); return false; }
|
||
}
|
||
return true;
|
||
}
|
||
async function save(): Promise<void> {
|
||
if (isSaving.value || !validate()) return;
|
||
if (!requestNo.value) requestNo.value = createPackageRequestNo();
|
||
isSaving.value = true;
|
||
try {
|
||
const itemList = items.value.map((item, index) => ({
|
||
productId: item.productId!,
|
||
productUnitId: item.productUnitId!,
|
||
quantity: normalizePackageQuantity(item.quantity ?? "")!,
|
||
unitPrice: canPriceOverride.value && item.unitPriceText ? parsePackageAmount(item.unitPriceText) : undefined,
|
||
sort: index,
|
||
remark: item.remark?.trim() || null
|
||
}));
|
||
const result = await SalesOrderAPI.createDirectProduct({
|
||
requestNo: requestNo.value,
|
||
customerId: customer.value!.id!,
|
||
purchasedAt: resolveTimestamp(purchasedAtText.value),
|
||
itemList,
|
||
attachmentList: buildAttachments(),
|
||
remark: remark.value.trim() || null
|
||
});
|
||
Message.success("销售订单已创建");
|
||
await router.replace(`/management/sales-orders/${result.id}`);
|
||
} catch (error) {
|
||
const message = getErrorMessage(error, "销售订单创建失败,重试会复用同一请求号");
|
||
Message.error(message);
|
||
}
|
||
finally { isSaving.value = false; }
|
||
}
|
||
onMounted(() => {
|
||
addItem();
|
||
navBarStore.clearRight();
|
||
});
|
||
onUnmounted(() => navBarStore.clearRight());
|
||
</script>
|
||
|
||
<style scoped lang="less">
|
||
.sales-order-create {
|
||
gap: 1rem;
|
||
display: flex;
|
||
padding: calc(var(--app-nav-height) + 1rem) 0 calc(6.5rem + env(safe-area-inset-bottom, 0));
|
||
flex-direction: column;
|
||
|
||
.form {
|
||
margin: 0 1rem;
|
||
padding: .5rem 0;
|
||
background: rgba(255, 255, 255, .92);
|
||
box-shadow: var(--td-shadow-1);
|
||
border-radius: 1.4rem;
|
||
|
||
.customer {
|
||
|
||
.actions {
|
||
gap: .5rem;
|
||
display: flex;
|
||
}
|
||
}
|
||
|
||
.code-scanner-wrapper,
|
||
.photo-part {
|
||
padding: 1rem;
|
||
}
|
||
|
||
.customer-profile {
|
||
margin: 1rem;
|
||
}
|
||
|
||
.time-actions {
|
||
gap: .5rem;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.product-part {
|
||
|
||
> .header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
|
||
strong {
|
||
font-size: .9375rem;
|
||
}
|
||
|
||
span {
|
||
color: var(--td-brand-color);
|
||
font-size: .75rem;
|
||
}
|
||
}
|
||
|
||
.tips {
|
||
margin-top: .25rem;
|
||
color: var(--td-text-color-secondary);
|
||
font-size: .75rem;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.items {
|
||
gap: .75rem;
|
||
display: flex;
|
||
margin-top: .75rem;
|
||
flex-direction: column;
|
||
|
||
.item {
|
||
border: 1px dashed var(--td-border-level-1-color);
|
||
padding: .5rem;
|
||
border-radius: .875rem;
|
||
|
||
.header {
|
||
gap: .625rem;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.no {
|
||
width: 1.75rem;
|
||
height: 1.75rem;
|
||
color: var(--td-brand-color);
|
||
flex: none;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: var(--td-brand-color-1);
|
||
border-radius: .625rem;
|
||
font-size: .6875rem;
|
||
font-weight: 700;
|
||
}
|
||
|
||
strong {
|
||
flex: 1;
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
color: var(--td-text-color-primary);
|
||
font-size: .875rem;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
}
|
||
}
|
||
|
||
.unit-list {
|
||
gap: .5rem;
|
||
width: 100%;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.unit-empty {
|
||
color: var(--td-text-color-secondary);
|
||
font-size: .75rem;
|
||
}
|
||
}
|
||
}
|
||
|
||
.price {
|
||
display: flex;
|
||
align-items: baseline;
|
||
justify-content: end;
|
||
|
||
.value {
|
||
font-size: 1.5rem;
|
||
}
|
||
}
|
||
|
||
.add {
|
||
--td-button-border-radius: 1rem;
|
||
|
||
gap: .375rem;
|
||
color: var(--td-brand-color);
|
||
margin-top: .75rem;
|
||
}
|
||
}
|
||
|
||
.textarea {
|
||
width: 100%;
|
||
}
|
||
|
||
.photo-part {
|
||
padding: 1rem;
|
||
}
|
||
}
|
||
|
||
.submit-wrap {
|
||
gap: 1rem;
|
||
left: 2rem;
|
||
right: 2rem;
|
||
border: 1px solid rgba(0, 0, 0, .05);
|
||
bottom: calc(env(safe-area-inset-bottom, 0) + 1rem);
|
||
z-index: 12;
|
||
display: flex;
|
||
padding: .5rem 1rem calc(.5rem + env(safe-area-inset-bottom, 0)) 1rem;
|
||
position: fixed;
|
||
align-items: center;
|
||
border-radius: 1.75rem;
|
||
backdrop-filter: blur(10px);
|
||
justify-content: space-between;
|
||
|
||
.total {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
|
||
span {
|
||
color: var(--td-text-color-secondary);
|
||
font-size: .6875rem;
|
||
}
|
||
|
||
.price {
|
||
display: flex;
|
||
align-items: baseline;
|
||
|
||
.value {
|
||
font-size: 1.5rem;
|
||
}
|
||
}
|
||
}
|
||
|
||
.submit {
|
||
--td-button-border-radius: 1rem;
|
||
}
|
||
}
|
||
}
|
||
|
||
:global(html.theme-dark) {
|
||
.sales-order-create {
|
||
.form {
|
||
background: rgba(15, 23, 42, .88);
|
||
box-shadow: 0 .75rem 2rem rgba(2, 6, 23, .32);
|
||
|
||
.order-item {
|
||
background: rgba(15, 23, 42, .72);
|
||
border-color: rgba(148, 163, 184, .16);
|
||
}
|
||
|
||
:deep(.textarea .t-textarea__inner) {
|
||
color: #e2e8f0;
|
||
background: rgba(15, 23, 42, .72);
|
||
border-color: rgba(148, 163, 184, .16);
|
||
}
|
||
}
|
||
|
||
.submit-bar {
|
||
box-shadow: 0 -.25rem 1rem rgba(0, 0, 0, .2);
|
||
background: rgba(15, 23, 42, .92);
|
||
}
|
||
}
|
||
}
|
||
</style>
|