feat(mobile-oa-h5): polish form layout and replace inputNumber with decimal field
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
a0775cf619
commit
b638c787b1
15 files changed
+471
-141
No files matched your search
@@ -5,11 +5,16 @@ import formCreateMobile from '@form-create/vant'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import './styles/tokens.css'
|
||||
import './styles/oa-form.css'
|
||||
import { registerOaComponents } from './oa/register-components'
|
||||
import { captureTokenFromUrl } from './utils/auth'
|
||||
|
||||
// 三墙主色(勿用 web-admin #10b981)
|
||||
document.documentElement.style.setProperty('--van-primary-color', '#0a9f6d')
|
||||
|
||||
// 须在路由/组件发请求前捕获小程序传入的 ?token=
|
||||
captureTokenFromUrl()
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(router)
|
||||
app.use(Vant)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
:model-value="displayText"
|
||||
readonly
|
||||
is-link
|
||||
input-align="left"
|
||||
:disabled="disabled"
|
||||
placeholder="请选择部门"
|
||||
@click="openPicker"
|
||||
@@ -15,7 +16,13 @@
|
||||
<strong>选择部门</strong>
|
||||
<span class="oa-pick__ok" @click="confirm">确定</span>
|
||||
</div>
|
||||
<van-search v-model="keyword" placeholder="搜索部门名称" />
|
||||
<van-search
|
||||
v-model="keyword"
|
||||
shape="round"
|
||||
label-align="left"
|
||||
input-align="left"
|
||||
placeholder="搜索部门名称"
|
||||
/>
|
||||
<div class="oa-pick__list">
|
||||
<template v-if="multiple">
|
||||
<van-checkbox-group v-model="pendingIds">
|
||||
@@ -26,8 +33,8 @@
|
||||
:title="d.label"
|
||||
@click="toggle(d.id)"
|
||||
>
|
||||
<template #right-icon>
|
||||
<van-checkbox :name="d.id" @click.stop />
|
||||
<template #icon>
|
||||
<van-checkbox class="oa-pick__check" :name="d.id" @click.stop />
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-checkbox-group>
|
||||
@@ -41,8 +48,8 @@
|
||||
:title="d.label"
|
||||
@click="pendingSingle = d.id"
|
||||
>
|
||||
<template #right-icon>
|
||||
<van-radio :name="d.id" @click.stop />
|
||||
<template #icon>
|
||||
<van-radio class="oa-pick__check" :name="d.id" @click.stop />
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-radio-group>
|
||||
@@ -187,26 +194,3 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.oa-pick__sheet {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
.oa-pick__hd {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 16px;
|
||||
border-bottom: 1px solid var(--border, #dcebe4);
|
||||
}
|
||||
.oa-pick__ok {
|
||||
color: var(--brand-green, #0a9f6d);
|
||||
font-weight: 600;
|
||||
}
|
||||
.oa-pick__list {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@
|
||||
v-model="text"
|
||||
type="number"
|
||||
inputmode="decimal"
|
||||
input-align="left"
|
||||
:disabled="disabled"
|
||||
:placeholder="placeholder"
|
||||
@update:model-value="onInput"
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div class="oa-number">
|
||||
<van-field
|
||||
v-model="text"
|
||||
type="number"
|
||||
inputmode="decimal"
|
||||
input-align="left"
|
||||
:disabled="disabled"
|
||||
:placeholder="placeholder"
|
||||
@update:model-value="onInput"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
defineOptions({ name: 'inputNumber' })
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: { type: [Number, String], default: null },
|
||||
disabled: { type: Boolean, default: false },
|
||||
placeholder: { type: String, default: '请输入数字' },
|
||||
formCreateInject: { type: Object, default: null }
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue', 'change'])
|
||||
|
||||
function toNum(v) {
|
||||
if (v == null || v === '') return null
|
||||
const n = typeof v === 'number' ? v : Number(String(v).replace(/,/g, ''))
|
||||
return Number.isFinite(n) ? n : null
|
||||
}
|
||||
|
||||
const text = ref(props.modelValue == null || props.modelValue === '' ? '' : String(props.modelValue))
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(v) => {
|
||||
const next = v == null || v === '' ? '' : String(v)
|
||||
if (next !== text.value) text.value = next
|
||||
}
|
||||
)
|
||||
|
||||
function onInput(v) {
|
||||
// 输入过程保留字符串便于输入小数点;失焦前尽量解析为 number
|
||||
const raw = v == null ? '' : String(v)
|
||||
text.value = raw
|
||||
if (raw === '' || raw === '-' || raw === '.' || raw.endsWith('.')) {
|
||||
emit('update:modelValue', raw === '' ? null : raw)
|
||||
emit('change', raw === '' ? null : raw)
|
||||
return
|
||||
}
|
||||
const n = toNum(raw)
|
||||
emit('update:modelValue', n)
|
||||
emit('change', n)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.oa-number {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@
|
||||
:model-value="displayText"
|
||||
readonly
|
||||
is-link
|
||||
input-align="left"
|
||||
:disabled="disabled"
|
||||
placeholder="请选择人员"
|
||||
@click="openPicker"
|
||||
@@ -15,7 +16,13 @@
|
||||
<strong>选择人员</strong>
|
||||
<span class="oa-pick__ok" @click="confirm">确定</span>
|
||||
</div>
|
||||
<van-search v-model="keyword" placeholder="搜索姓名或工号" />
|
||||
<van-search
|
||||
v-model="keyword"
|
||||
shape="round"
|
||||
label-align="left"
|
||||
input-align="left"
|
||||
placeholder="搜索姓名或工号"
|
||||
/>
|
||||
<div class="oa-pick__list">
|
||||
<template v-if="multiple">
|
||||
<van-checkbox-group v-model="pendingIds">
|
||||
@@ -27,8 +34,8 @@
|
||||
:label="u.sub || undefined"
|
||||
@click="toggle(u.id)"
|
||||
>
|
||||
<template #right-icon>
|
||||
<van-checkbox :name="u.id" @click.stop />
|
||||
<template #icon>
|
||||
<van-checkbox class="oa-pick__check" :name="u.id" @click.stop />
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-checkbox-group>
|
||||
@@ -43,8 +50,8 @@
|
||||
:label="u.sub || undefined"
|
||||
@click="pendingSingle = u.id"
|
||||
>
|
||||
<template #right-icon>
|
||||
<van-radio :name="u.id" @click.stop />
|
||||
<template #icon>
|
||||
<van-radio class="oa-pick__check" :name="u.id" @click.stop />
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-radio-group>
|
||||
@@ -150,7 +157,7 @@ function confirm() {
|
||||
async function loadUsers() {
|
||||
loading.value = true
|
||||
try {
|
||||
const pageSize = 200
|
||||
const pageSize = 100
|
||||
const raw = []
|
||||
let page = 1
|
||||
for (;;) {
|
||||
@@ -200,27 +207,3 @@ onMounted(() => {
|
||||
loadUsers()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.oa-pick__sheet {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
.oa-pick__hd {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 16px;
|
||||
border-bottom: 1px solid var(--border, #dcebe4);
|
||||
}
|
||||
.oa-pick__ok {
|
||||
color: var(--brand-green, #0a9f6d);
|
||||
font-weight: 600;
|
||||
}
|
||||
.oa-pick__list {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@
|
||||
:model-value="displayText"
|
||||
readonly
|
||||
is-link
|
||||
input-align="left"
|
||||
:disabled="disabled"
|
||||
placeholder="请选择职位"
|
||||
@click="openPicker"
|
||||
@@ -15,7 +16,13 @@
|
||||
<strong>选择职位</strong>
|
||||
<span class="oa-pick__ok" @click="confirm">确定</span>
|
||||
</div>
|
||||
<van-search v-model="keyword" placeholder="搜索职位名称或编码" />
|
||||
<van-search
|
||||
v-model="keyword"
|
||||
shape="round"
|
||||
label-align="left"
|
||||
input-align="left"
|
||||
placeholder="搜索职位名称或编码"
|
||||
/>
|
||||
<div class="oa-pick__list">
|
||||
<template v-if="multiple">
|
||||
<van-checkbox-group v-model="pendingIds">
|
||||
@@ -27,8 +34,8 @@
|
||||
:label="p.sub || undefined"
|
||||
@click="toggle(p.id)"
|
||||
>
|
||||
<template #right-icon>
|
||||
<van-checkbox :name="p.id" @click.stop />
|
||||
<template #icon>
|
||||
<van-checkbox class="oa-pick__check" :name="p.id" @click.stop />
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-checkbox-group>
|
||||
@@ -43,8 +50,8 @@
|
||||
:label="p.sub || undefined"
|
||||
@click="pendingSingle = p.id"
|
||||
>
|
||||
<template #right-icon>
|
||||
<van-radio :name="p.id" @click.stop />
|
||||
<template #icon>
|
||||
<van-radio class="oa-pick__check" :name="p.id" @click.stop />
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-radio-group>
|
||||
@@ -150,7 +157,7 @@ function confirm() {
|
||||
async function loadPosts() {
|
||||
loading.value = true
|
||||
try {
|
||||
const pageSize = 200
|
||||
const pageSize = 100
|
||||
const raw = []
|
||||
let page = 1
|
||||
for (;;) {
|
||||
@@ -197,26 +204,3 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.oa-pick__sheet {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
.oa-pick__hd {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 16px;
|
||||
border-bottom: 1px solid var(--border, #dcebe4);
|
||||
}
|
||||
.oa-pick__ok {
|
||||
color: var(--brand-green, #0a9f6d);
|
||||
font-weight: 600;
|
||||
}
|
||||
.oa-pick__list {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@
|
||||
:model-value="summary"
|
||||
readonly
|
||||
is-link
|
||||
input-align="left"
|
||||
:disabled="disabled"
|
||||
placeholder="请选择收款账户"
|
||||
@click="openPicker"
|
||||
@@ -21,7 +22,13 @@
|
||||
<strong>选择收款账户</strong>
|
||||
<span class="oa-recv__ok" @click="confirm">确定</span>
|
||||
</div>
|
||||
<van-search v-model="keyword" placeholder="搜索账户名称或账号" />
|
||||
<van-search
|
||||
v-model="keyword"
|
||||
shape="round"
|
||||
label-align="left"
|
||||
input-align="left"
|
||||
placeholder="搜索账户名称或账号"
|
||||
/>
|
||||
<div class="oa-recv__list">
|
||||
<van-checkbox-group v-model="pendingIds">
|
||||
<van-cell
|
||||
@@ -31,8 +38,8 @@
|
||||
:title="a.label"
|
||||
@click="toggle(a.id)"
|
||||
>
|
||||
<template #right-icon>
|
||||
<van-checkbox :name="a.id" @click.stop />
|
||||
<template #icon>
|
||||
<van-checkbox class="oa-recv__check" :name="a.id" @click.stop />
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-checkbox-group>
|
||||
@@ -146,29 +153,9 @@ onMounted(() => {
|
||||
color: var(--text-muted, #6b7b74);
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
text-align: left;
|
||||
}
|
||||
.oa-recv__line + .oa-recv__line {
|
||||
margin-top: 4px;
|
||||
}
|
||||
.oa-recv__sheet {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
.oa-recv__hd {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 16px;
|
||||
border-bottom: 1px solid var(--border, #dcebe4);
|
||||
}
|
||||
.oa-recv__ok {
|
||||
color: var(--brand-green, #0a9f6d);
|
||||
font-weight: 600;
|
||||
}
|
||||
.oa-recv__list {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -61,6 +61,9 @@
|
||||
</van-tabs>
|
||||
<van-search
|
||||
v-model="keyword"
|
||||
shape="round"
|
||||
label-align="left"
|
||||
input-align="left"
|
||||
placeholder="搜索流程名 / 标题"
|
||||
@search="loadCandidates"
|
||||
/>
|
||||
@@ -74,8 +77,8 @@
|
||||
:label="pickerLabel(row)"
|
||||
@click="toggle(row.id)"
|
||||
>
|
||||
<template #right-icon>
|
||||
<van-checkbox :name="row.id" @click.stop />
|
||||
<template #icon>
|
||||
<van-checkbox class="oa-rel__check" :name="row.id" @click.stop />
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-checkbox-group>
|
||||
@@ -266,25 +269,4 @@ watch(
|
||||
flex: 0 0 auto;
|
||||
color: #94a3b8;
|
||||
}
|
||||
.oa-rel__sheet {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
.oa-rel__hd {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 16px;
|
||||
border-bottom: 1px solid var(--border, #dcebe4);
|
||||
}
|
||||
.oa-rel__ok {
|
||||
color: var(--brand-green, #0a9f6d);
|
||||
font-weight: 600;
|
||||
}
|
||||
.oa-rel__picker {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -3,6 +3,7 @@
|
||||
<div class="oa-stub__title">{{ title || typeName }}</div>
|
||||
<van-field
|
||||
v-model="inner"
|
||||
input-align="left"
|
||||
:placeholder="'[' + typeName + '] 占位,后续替换真实交互'"
|
||||
@update:model-value="onInput"
|
||||
/>
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
<van-field
|
||||
:model-value="leg.transport"
|
||||
label="交通工具"
|
||||
label-align="top"
|
||||
input-align="left"
|
||||
readonly
|
||||
is-link
|
||||
:disabled="disabled"
|
||||
@@ -25,6 +27,8 @@
|
||||
<van-field
|
||||
:model-value="leg.tripType"
|
||||
label="单程往返"
|
||||
label-align="top"
|
||||
input-align="left"
|
||||
readonly
|
||||
is-link
|
||||
:disabled="disabled"
|
||||
@@ -34,6 +38,8 @@
|
||||
<van-field
|
||||
:model-value="leg.fromCity"
|
||||
label="出发城市"
|
||||
label-align="top"
|
||||
input-align="left"
|
||||
:disabled="disabled"
|
||||
placeholder="请输入"
|
||||
@update:model-value="(v) => patch(idx, { fromCity: v })"
|
||||
@@ -41,6 +47,8 @@
|
||||
<van-field
|
||||
:model-value="leg.toCity"
|
||||
label="目的城市"
|
||||
label-align="top"
|
||||
input-align="left"
|
||||
:disabled="disabled"
|
||||
placeholder="请输入"
|
||||
@update:model-value="(v) => patch(idx, { toCity: v })"
|
||||
@@ -48,6 +56,8 @@
|
||||
<van-field
|
||||
:model-value="leg.startDate"
|
||||
label="开始日期"
|
||||
label-align="top"
|
||||
input-align="left"
|
||||
readonly
|
||||
is-link
|
||||
:disabled="disabled"
|
||||
@@ -57,6 +67,8 @@
|
||||
<van-field
|
||||
:model-value="leg.startHalf"
|
||||
label="开始时段"
|
||||
label-align="top"
|
||||
input-align="left"
|
||||
readonly
|
||||
is-link
|
||||
:disabled="disabled"
|
||||
@@ -65,6 +77,8 @@
|
||||
<van-field
|
||||
:model-value="leg.endDate"
|
||||
label="结束日期"
|
||||
label-align="top"
|
||||
input-align="left"
|
||||
readonly
|
||||
is-link
|
||||
:disabled="disabled"
|
||||
@@ -74,6 +88,8 @@
|
||||
<van-field
|
||||
:model-value="leg.endHalf"
|
||||
label="结束时段"
|
||||
label-align="top"
|
||||
input-align="left"
|
||||
readonly
|
||||
is-link
|
||||
:disabled="disabled"
|
||||
@@ -82,6 +98,8 @@
|
||||
<van-field
|
||||
:model-value="leg.duration == null ? '' : String(leg.duration)"
|
||||
label="时长(天)"
|
||||
label-align="top"
|
||||
input-align="left"
|
||||
type="number"
|
||||
:disabled="disabled"
|
||||
@update:model-value="(v) => patch(idx, { duration: v === '' ? null : Number(v) })"
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/** OA 表单全局 option:标题在上、内容左对齐(覆盖 form-create/vant 默认右对齐) */
|
||||
export const oaFormOption = {
|
||||
submitBtn: false,
|
||||
resetBtn: false,
|
||||
form: {
|
||||
labelAlign: 'top',
|
||||
inputAlign: 'left',
|
||||
colon: false
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
/** 按 zkxw-sc 已发布模板实际出现的 type 构造;套件带 children(与 Web 结构一致) */
|
||||
import { oaFormOption } from './form-option.js'
|
||||
|
||||
const LEAVE_TYPE_OPTIONS = [
|
||||
{ label: '事假', value: '事假' },
|
||||
@@ -39,7 +40,7 @@ export const kitchenSinkRule = [
|
||||
{ label: '紧急', value: 'urgent' }
|
||||
]
|
||||
},
|
||||
{ type: 'inputNumber', field: 'qty', title: '数字', value: 1 },
|
||||
{ type: 'inputNumber', field: 'qty', title: '数字', value: 1, props: { placeholder: '请输入数字,可含小数' } },
|
||||
{
|
||||
type: 'datePicker',
|
||||
field: 'bizDate',
|
||||
@@ -277,7 +278,5 @@ export const kitchenSinkRule = [
|
||||
]
|
||||
|
||||
export const kitchenSinkOption = {
|
||||
submitBtn: false,
|
||||
resetBtn: false,
|
||||
form: { labelPosition: 'top' }
|
||||
...oaFormOption
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import OaMoneyField from './components/OaMoneyField.vue'
|
||||
import OaNumberField from './components/OaNumberField.vue'
|
||||
import OaUploadField from './components/OaUploadField.vue'
|
||||
import OaReceiveAccountSelect from './components/OaReceiveAccountSelect.vue'
|
||||
import OaRelatedApproval from './components/OaRelatedApproval.vue'
|
||||
@@ -12,6 +13,7 @@ import OaTripItinerary from './components/OaTripItinerary.vue'
|
||||
|
||||
/** 与 web-admin type 名对齐 */
|
||||
const REAL_COMPONENTS = {
|
||||
inputNumber: OaNumberField,
|
||||
money: OaMoneyField,
|
||||
upload: OaUploadField,
|
||||
receiveAccount: OaReceiveAccountSelect,
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
/* form-create + Vant:上下布局与左对齐兜底 */
|
||||
.form-create-m .van-field__label--top {
|
||||
width: 100%;
|
||||
margin-bottom: 6px;
|
||||
text-align: left;
|
||||
color: var(--text-primary, #1f2a26);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.form-create-m .van-field__control {
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.form-create-m .van-field__control::placeholder {
|
||||
text-align: left;
|
||||
color: var(--text-muted, #6b7b74);
|
||||
}
|
||||
|
||||
.form-create-m .fc-form-item {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
/* 自定义控件 / 内置选择触发条:占满整行,箭头贴右 */
|
||||
.form-create-m ._fc-select,
|
||||
.form-create-m ._fc-date-picker,
|
||||
.form-create-m ._fc-time-picker,
|
||||
.form-create-m ._fc-calendar,
|
||||
.form-create-m ._fc-cascader,
|
||||
.form-create-m .oa-pick,
|
||||
.form-create-m .oa-money,
|
||||
.form-create-m .oa-number,
|
||||
.form-create-m .oa-recv,
|
||||
.form-create-m .oa-rel,
|
||||
.form-create-m .oa-trip,
|
||||
.form-create-m .oa-upload {
|
||||
display: block;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/*
|
||||
* 内层触发 Field 会继承 Form 的 labelAlign=top,导致 value 占满一行、箭头折到下一行最左。
|
||||
* 这里强制单行横排:value 撑满,right-icon 固定右侧。
|
||||
*/
|
||||
.form-create-m ._fc-select > .van-cell,
|
||||
.form-create-m ._fc-date-picker > .van-cell,
|
||||
.form-create-m ._fc-time-picker > .van-cell,
|
||||
.form-create-m ._fc-calendar > .van-cell,
|
||||
.form-create-m ._fc-cascader > .van-cell,
|
||||
.form-create-m .oa-pick > .van-cell,
|
||||
.form-create-m .oa-money > .van-cell,
|
||||
.form-create-m .oa-number > .van-cell,
|
||||
.form-create-m .oa-recv > .van-cell {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-create-m ._fc-select > .van-cell > .van-cell__title,
|
||||
.form-create-m ._fc-date-picker > .van-cell > .van-cell__title,
|
||||
.form-create-m ._fc-time-picker > .van-cell > .van-cell__title,
|
||||
.form-create-m ._fc-calendar > .van-cell > .van-cell__title,
|
||||
.form-create-m ._fc-cascader > .van-cell > .van-cell__title,
|
||||
.form-create-m .oa-pick > .van-cell > .van-cell__title,
|
||||
.form-create-m .oa-recv > .van-cell > .van-cell__title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.form-create-m ._fc-select > .van-cell > .van-cell__value,
|
||||
.form-create-m ._fc-date-picker > .van-cell > .van-cell__value,
|
||||
.form-create-m ._fc-time-picker > .van-cell > .van-cell__value,
|
||||
.form-create-m ._fc-calendar > .van-cell > .van-cell__value,
|
||||
.form-create-m ._fc-cascader > .van-cell > .van-cell__value,
|
||||
.form-create-m .oa-pick > .van-cell > .van-cell__value,
|
||||
.form-create-m .oa-money > .van-cell > .van-cell__value,
|
||||
.form-create-m .oa-number > .van-cell > .van-cell__value,
|
||||
.form-create-m .oa-recv > .van-cell > .van-cell__value {
|
||||
flex: 1 1 auto;
|
||||
width: auto !important;
|
||||
max-width: none !important;
|
||||
min-width: 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.form-create-m ._fc-select > .van-cell > .van-cell__right-icon,
|
||||
.form-create-m ._fc-date-picker > .van-cell > .van-cell__right-icon,
|
||||
.form-create-m ._fc-time-picker > .van-cell > .van-cell__right-icon,
|
||||
.form-create-m ._fc-calendar > .van-cell > .van-cell__right-icon,
|
||||
.form-create-m ._fc-cascader > .van-cell > .van-cell__right-icon,
|
||||
.form-create-m .oa-pick > .van-cell > .van-cell__right-icon,
|
||||
.form-create-m .oa-recv > .van-cell > .van-cell__right-icon {
|
||||
flex: 0 0 auto;
|
||||
margin-left: 8px;
|
||||
order: 3;
|
||||
}
|
||||
|
||||
/* 行程内带自身 label 的 Field:标题在上,箭头仍在内容行右侧 */
|
||||
.form-create-m .oa-trip .van-field--label-top {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-create-m .oa-trip .van-field--label-top > .van-cell__title {
|
||||
flex: 0 0 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-create-m .oa-trip .van-field--label-top > .van-cell__value {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.form-create-m .oa-trip .van-field--label-top > .van-cell__right-icon {
|
||||
flex: 0 0 auto;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
/* 外层表单项:标题独占一行;内容区整行左对齐(箭头在内层控件右侧) */
|
||||
.form-create-m .fc-form-item.van-field--label-top {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.form-create-m .fc-form-item.van-field--label-top > .van-cell__title {
|
||||
flex: 0 0 100%;
|
||||
width: 100%;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.form-create-m .fc-form-item.van-field--label-top > .van-cell__value {
|
||||
flex: 1 1 100%;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* 选择弹窗通用 */
|
||||
.oa-pick__sheet,
|
||||
.oa-recv__sheet,
|
||||
.oa-rel__sheet {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.oa-pick__hd,
|
||||
.oa-recv__hd,
|
||||
.oa-rel__hd {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 16px;
|
||||
border-bottom: 1px solid var(--border, #dcebe4);
|
||||
}
|
||||
|
||||
.oa-pick__hd strong,
|
||||
.oa-recv__hd strong,
|
||||
.oa-rel__hd strong {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary, #1f2a26);
|
||||
}
|
||||
|
||||
.oa-pick__hd > span:first-child,
|
||||
.oa-recv__hd > span:first-child,
|
||||
.oa-rel__hd > span:first-child {
|
||||
min-width: 48px;
|
||||
color: var(--text-muted, #6b7b74);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.oa-pick__ok,
|
||||
.oa-recv__ok,
|
||||
.oa-rel__ok {
|
||||
min-width: 48px;
|
||||
color: var(--brand-green, #0a9f6d);
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.oa-pick__list,
|
||||
.oa-recv__list,
|
||||
.oa-rel__picker {
|
||||
flex: 1;
|
||||
padding: 12px;
|
||||
overflow: auto;
|
||||
background: transparent;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.oa-pick__list .van-cell,
|
||||
.oa-recv__list .van-cell,
|
||||
.oa-rel__picker .van-cell {
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
padding: 12px 14px;
|
||||
text-align: left;
|
||||
background: transparent;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.oa-pick__list .van-cell:last-child,
|
||||
.oa-recv__list .van-cell:last-child,
|
||||
.oa-rel__picker .van-cell:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.oa-pick__list .van-cell::after,
|
||||
.oa-recv__list .van-cell::after,
|
||||
.oa-rel__picker .van-cell::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.oa-pick__list .van-cell__title,
|
||||
.oa-recv__list .van-cell__title,
|
||||
.oa-rel__picker .van-cell__title {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.oa-pick__list .van-cell__label,
|
||||
.oa-recv__list .van-cell__label,
|
||||
.oa-rel__picker .van-cell__label {
|
||||
text-align: left;
|
||||
color: var(--text-muted, #6b7b74);
|
||||
}
|
||||
|
||||
.oa-pick__check,
|
||||
.oa-recv__check,
|
||||
.oa-rel__check {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* 弹窗检索:勿继承表单 labelAlign=top,保持单行垂直居中 */
|
||||
.oa-pick__sheet .van-search,
|
||||
.oa-recv__sheet .van-search,
|
||||
.oa-rel__sheet .van-search {
|
||||
padding: 10px 12px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.oa-pick__sheet .van-search .van-search__content,
|
||||
.oa-recv__sheet .van-search .van-search__content,
|
||||
.oa-rel__sheet .van-search .van-search__content {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.oa-pick__sheet .van-search .van-cell,
|
||||
.oa-recv__sheet .van-search .van-cell,
|
||||
.oa-rel__sheet .van-search .van-cell {
|
||||
align-items: center;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
.oa-pick__sheet .van-search .van-field__body,
|
||||
.oa-recv__sheet .van-search .van-field__body,
|
||||
.oa-rel__sheet .van-search .van-field__body {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.oa-pick__sheet .van-search .van-field__control,
|
||||
.oa-recv__sheet .van-search .van-field__control,
|
||||
.oa-rel__sheet .van-search .van-field__control {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
text-align: left !important;
|
||||
}
|
||||
@@ -1,9 +1,45 @@
|
||||
/** 从 URL ?token= 读取登录态(小程序 web-view 传入) */
|
||||
export function getToken() {
|
||||
/** 小程序 web-view 通过 URL ?token= 传入登录态;落盘避免路由跳转后丢失 */
|
||||
const TOKEN_KEY = 'zkxw_oa_h5_token'
|
||||
|
||||
function readQueryToken() {
|
||||
try {
|
||||
const q = new URLSearchParams(window.location.search)
|
||||
const q = new URLSearchParams(window.location.search || '')
|
||||
return String(q.get('token') || '').trim()
|
||||
} catch {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
/** 启动时调用:把 URL 中的 token 写入 sessionStorage,并尽量从地址栏摘掉敏感参数 */
|
||||
export function captureTokenFromUrl() {
|
||||
const fromQuery = readQueryToken()
|
||||
if (fromQuery) {
|
||||
try {
|
||||
sessionStorage.setItem(TOKEN_KEY, fromQuery)
|
||||
} catch {
|
||||
/* ignore quota / private mode */
|
||||
}
|
||||
try {
|
||||
const url = new URL(window.location.href)
|
||||
if (url.searchParams.has('token')) {
|
||||
url.searchParams.delete('token')
|
||||
const next = `${url.pathname}${url.search}${url.hash}`
|
||||
window.history.replaceState(window.history.state, '', next)
|
||||
}
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
return fromQuery
|
||||
}
|
||||
return getToken()
|
||||
}
|
||||
|
||||
export function getToken() {
|
||||
try {
|
||||
const cached = String(sessionStorage.getItem(TOKEN_KEY) || '').trim()
|
||||
if (cached) return cached
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
return readQueryToken()
|
||||
}
|
||||
Reference in new issue
Block a user