Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mp-enterprise-people-recruitment-h5
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
彭佳妮(贵阳日报)
mp-enterprise-people-recruitment-h5
Commits
373a242f
Commit
373a242f
authored
Oct 25, 2024
by
李明环(东信)
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
表单组件 创建工作步骤1
parent
10eb7e7a
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
233 additions
and
964 deletions
+233
-964
settings.json
.vscode/settings.json
+1
-1
form-item.vue
src/components/form/form-item.vue
+50
-0
form-row.vue
src/components/form/form-row.vue
+20
-0
selectbox.vue
src/components/form/selectbox.vue
+87
-0
index.scss
src/components/wd-col-picker22/index.scss
+0
-267
types.ts
src/components/wd-col-picker22/types.ts
+0
-171
wd-col-picker.vue
src/components/wd-col-picker22/wd-col-picker.vue
+0
-502
step1.vue
src/pages/recommend/releasePostion/step1.vue
+73
-19
step2.vue
src/pages/recommend/releasePostion/step2.vue
+2
-3
step4.vue
src/pages/recommend/releasePostion/step4.vue
+0
-1
arrow.png
src/static/image/icon/arrow.png
+0
-0
No files found.
.vscode/settings.json
View file @
373a242f
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
"files.eol"
:
"
\n
"
,
"files.eol"
:
"
\n
"
,
"typescript.tsdk"
:
"node_modules/typescript/lib"
,
"typescript.tsdk"
:
"node_modules/typescript/lib"
,
"[vue]"
:
{
"[vue]"
:
{
"editor.defaultFormatter"
:
"
octref.vetur
"
"editor.defaultFormatter"
:
"
esbenp.prettier-vscode
"
},
},
"[typescript]"
:
{
"[typescript]"
:
{
"editor.defaultFormatter"
:
"esbenp.prettier-vscode"
"editor.defaultFormatter"
:
"esbenp.prettier-vscode"
...
...
src/components/form/form-item.vue
0 → 100644
View file @
373a242f
<
template
>
<div
class=
"form-item"
:style=
"
{ borderWidth: props.border ? '2rpx' : '0' }">
<p
class=
"title"
>
{{
props
.
title
}}
</p>
<img
v-if=
"icon"
class=
"icon"
:src=
"iconPath"
alt=
""
/>
<slot></slot>
</div>
</
template
>
<
script
setup
lang=
"ts"
>
const
props
=
defineProps
({
// 标题
title
:
{
type
:
String
,
default
:
()
=>
"默认title"
},
// 边框
border
:
{
type
:
Boolean
,
default
:
()
=>
true
},
// 图标 (如果为空不显示)
icon
:
{
type
:
String
as
PropType
<
"arrow"
|
"edit"
|
""
>
,
default
:
()
=>
"arrow"
}
});
const
iconPath
=
new
URL
(
`../../static/image/icon/
${
props
.
icon
}
.png`
,
import
.
meta
.
url
).
href
;
</
script
>
<
style
lang=
"scss"
scoped
>
.form-item
{
position
:
relative
;
padding-bottom
:
16rpx
;
margin-top
:
32rpx
;
border-bottom
:
2rpx
solid
rgb
(
31
35
41
/
15%
);
.title
{
margin-bottom
:
32rpx
;
font-size
:
32rpx
;
font-weight
:
600
;
line-height
:
36rpx
;
}
.icon
{
position
:
absolute
;
right
:
20rpx
;
bottom
:
24rpx
;
width
:
28rpx
;
height
:
28rpx
;
}
}
</
style
>
src/components/form/form-row.vue
0 → 100644
View file @
373a242f
<
template
>
<div
class=
"form-row"
:style=
"
{ gridTemplateColumns: props.fill ? '1fr' : '1fr 1fr' }">
<slot></slot>
</div>
</
template
>
<
script
setup
>
const
props
=
defineProps
({
fill
:
{
type
:
Boolean
,
default
:
()
=>
true
}
});
</
script
>
<
style
lang=
"scss"
scoped
>
.form-row
{
display
:
grid
;
}
</
style
>
src/components/form/selectbox.vue
0 → 100644
View file @
373a242f
<
template
>
<div
class=
"selectbox"
>
<div
v-for=
"v in props.options"
:class=
"
{ item: true, active: isActive(v) }"
:key="v[props.valueKey]"
@click="onClickItem(v)"
>
{{
v
[
props
.
labelKey
]
}}
</div>
</div>
</
template
>
<
script
setup
>
const
props
=
defineProps
({
// 默认值
modelValue
:
{
type
:
[
String
,
Number
,
Array
],
default
:
()
=>
""
},
//值的键
valueKey
:
{
type
:
String
,
default
:
()
=>
"value"
},
//label的键
labelKey
:
{
type
:
String
,
default
:
()
=>
"label"
},
// 是否多选
multiple
:
{
type
:
Boolean
,
default
:
()
=>
false
},
// 默认值
options
:
{
type
:
Array
,
default
:
()
=>
[]
}
});
const
emit
=
defineEmits
([
"update:modelValue"
]);
// 激活类名
const
isActive
=
e
=>
{
if
(
props
.
multiple
)
{
return
props
.
modelValue
.
includes
(
e
[
props
.
valueKey
]);
}
else
{
return
props
.
modelValue
===
e
[
props
.
valueKey
];
}
};
// 点击选项
const
onClickItem
=
e
=>
{
const
value
=
e
[
props
.
valueKey
];
if
(
props
.
multiple
)
{
const
index
=
props
.
modelValue
.
indexOf
(
value
);
if
(
index
>
-
1
)
{
emit
(
"update:modelValue"
,
props
.
modelValue
.
slice
(
index
,
1
));
}
else
{
emit
(
"update:modelValue"
,
[...
props
.
modelValue
,
value
]);
}
}
else
{
emit
(
"update:modelValue"
,
value
);
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.selectbox
{
display
:
grid
;
grid-template-columns
:
repeat
(
4
,
1fr
);
gap
:
8px
;
.item
{
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
height
:
32px
;
font-size
:
12px
;
color
:
#1f86ff
;
background
:
#1f86ff
0f
;
border-radius
:
4px
;
}
.active
{
color
:
#ffffff
;
background
:
#1f86ff
;
}
}
</
style
>
src/components/wd-col-picker22/index.scss
deleted
100644 → 0
View file @
10eb7e7a
@import
"wot-design-uni/components/common/abstracts/variable"
;
@import
"wot-design-uni/components/common/abstracts/mixin"
;
.wot-theme-dark
{
@include
b
(
col-picker
)
{
@include
when
(
border
)
{
.wd-col-picker__cell
{
@include
halfPixelBorder
(
"top"
,
$-cell-padding
,
$-dark-border-color
);
}
}
@include
e
(
label
)
{
color
:
$-dark-color
;
}
@include
e
(
cell
)
{
color
:
$-dark-color
;
background-color
:
$-dark-background2
;
@include
when
(
disabled
)
{
.wd-col-picker__value
{
color
:
$-dark-color3
;
}
}
}
@include
e
(
list-item
)
{
@include
when
(
disabled
)
{
color
:
$-dark-color3
;
}
}
@include
e
(
list-item-tip
)
{
color
:
$-dark-color-gray
;
}
@include
e
(
value
)
{
color
:
$-dark-color
;
@include
m
(
placeholder
)
{
color
:
$-dark-color-gray
;
}
}
:deep
(
.wd-col-picker__arrow
)
{
color
:
$-dark-color
;
}
@include
e
(
list
)
{
color
:
$-dark-color
;
}
@include
e
(
selected
)
{
color
:
$-dark-color
;
}
}
}
.tags
{
gap
:
32rpx
;
padding
:
0
32rpx
;
div
{
padding
:
8rpx
16rpx
;
font-size
:
24rpx
;
color
:
#4d80f0
;
background-color
:
#4d80f0
1f
;
}
}
@include
b
(
col-picker
)
{
@include
when
(
border
)
{
.wd-col-picker__cell
{
@include
halfPixelBorder
(
"top"
,
$-cell-padding
);
}
}
@include
e
(
cell
)
{
position
:
relative
;
display
:
flex
;
align-items
:
flex-start
;
padding
:
$-cell-wrapper-padding
$-cell-padding
;
overflow
:
hidden
;
font-size
:
$-cell-title-fs
;
line-height
:
$-cell-line-height
;
color
:
$-cell-title-color
;
text-decoration
:
none
;
background-color
:
$-color-white
;
}
@include
e
(
cell
)
{
@include
when
(
disabled
)
{
.wd-col-picker__value
{
color
:
$-input-disabled-color
;
}
}
@include
when
(
align-right
)
{
.wd-col-picker__value
{
text-align
:
right
;
}
}
@include
when
(
error
)
{
.wd-col-picker__value
{
color
:
$-input-error-color
;
}
:deep
(
.wd-col-picker__arrow
)
{
color
:
$-input-error-color
;
}
}
@include
when
(
large
)
{
font-size
:
$-cell-title-fs-large
;
:deep
(
.wd-col-picker__arrow
)
{
font-size
:
$-cell-icon-size-large
;
}
}
}
@include
e
(
error-message
)
{
font-size
:
$-form-item-error-message-font-size
;
line-height
:
$-form-item-error-message-line-height
;
color
:
$-form-item-error-message-color
;
text-align
:
left
;
vertical-align
:
middle
;
}
@include
e
(
label
)
{
position
:
relative
;
box-sizing
:
border-box
;
width
:
$-input-cell-label-width
;
margin-right
:
$-cell-padding
;
color
:
$-cell-title-color
;
@include
when
(
required
)
{
padding-left
:
12px
;
&
:
:
after
{
position
:
absolute
;
top
:
2px
;
left
:
0
;
font-size
:
$-cell-required-size
;
line-height
:
1
.1
;
color
:
$-cell-required-color
;
content
:
"*"
;
}
}
}
@include
e
(
value-wraper
)
{
display
:
flex
;
}
@include
e
(
value
)
{
flex
:
1
;
margin-right
:
10px
;
color
:
$-cell-value-color
;
@include
when
(
ellipsis
)
{
@include
lineEllipsis
;
}
@include
m
(
placeholder
)
{
color
:
$-input-placeholder-color
;
}
}
@include
e
(
body
)
{
flex
:
1
;
}
@include
edeep
(
arrow
)
{
display
:
block
;
font-size
:
$-cell-icon-size
;
line-height
:
$-cell-line-height
;
color
:
$-cell-arrow-color
;
}
@include
e
(
selected
)
{
height
:
$-col-picker-selected-height
;
overflow
:
hidden
;
font-size
:
$-col-picker-selected-fs
;
color
:
$-col-picker-selected-color
;
}
@include
e
(
selected-container
)
{
position
:
relative
;
display
:
flex
;
user-select
:
none
;
}
@include
e
(
selected-item
)
{
flex
:
0
0
auto
;
height
:
$-col-picker-selected-height
;
padding
:
$-col-picker-selected-padding
;
line-height
:
$-col-picker-selected-height
;
@include
when
(
selected
)
{
font-weight
:
$-col-picker-selected-fw
;
}
}
@include
e
(
selected-line
)
{
position
:
absolute
;
bottom
:
5px
;
left
:
0
;
z-index
:
1
;
width
:
$-col-picker-line-width
;
height
:
$-col-picker-line-height
;
background
:
$-col-picker-line-color
;
border-radius
:
calc
(
$-col-picker-line-height
/
2
);
box-shadow
:
$-col-picker-line-box-shadow
;
}
@include
e
(
list-container
)
{
position
:
relative
;
}
@include
e
(
list
)
{
box-sizing
:
border-box
;
height
:
$-col-picker-list-height
;
padding-bottom
:
$-col-picker-list-padding-bottom
;
overflow
:
auto
;
font-size
:
$-col-picker-list-fs
;
color
:
$-col-picker-list-color
;
-webkit-overflow-scrolling
:
touch
;
}
@include
e
(
list-item
)
{
display
:
flex
;
align-items
:
flex-start
;
padding
:
$-col-picker-list-item-padding
;
@include
when
(
selected
)
{
color
:
$-col-picker-list-color-checked
;
:deep
(
.wd-col-picker__checked
)
{
opacity
:
1
;
}
}
@include
when
(
disabled
)
{
color
:
$-col-picker-list-color-disabled
;
}
}
@include
e
(
list-item-label
)
{
line-height
:
1
.285
;
}
@include
e
(
list-item-tip
)
{
margin-top
:
2px
;
font-size
:
$-col-picker-list-fs-tip
;
color
:
$-col-picker-list-color-tip
;
}
@include
edeep
(
checked
)
{
display
:
block
;
margin-left
:
4px
;
font-size
:
$-col-picker-list-checked-icon-size
;
color
:
$-col-picker-list-color-checked
;
opacity
:
0
;
}
@include
e
(
loading
)
{
position
:
absolute
;
inset
:
0
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
}
src/components/wd-col-picker22/types.ts
deleted
100644 → 0
View file @
10eb7e7a
import
type
{
ComponentPublicInstance
,
ExtractPropTypes
,
PropType
}
from
"vue"
;
import
{
baseProps
,
makeArrayProp
,
makeBooleanProp
,
makeNumberProp
,
makeRequiredProp
,
makeStringProp
}
from
"wot-design-uni/components/common/props"
;
import
type
{
FormItemRule
}
from
"wot-design-uni/components/wd-form/types"
;
export
const
colPickerProps
=
{
...
baseProps
,
/**
* 选中项
*/
modelValue
:
makeRequiredProp
(
Array
as
PropType
<
Array
<
string
|
number
>>
),
/* 多选数据 */
mValue
:
{
type
:
Array
,
default
:
()
=>
[]
},
mMax
:
{
type
:
Number
,
default
:
1
},
/**
* 选择器数据,二维数组
*/
columns
:
makeArrayProp
<
Record
<
string
,
any
>
[]
>
(),
/**
* 选择器左侧文案
*/
label
:
String
,
/**
* 设置左侧标题宽度
*/
labelWidth
:
makeStringProp
(
"33%"
),
/**
* 使用 label 插槽时设置该选项
*/
useLabelSlot
:
makeBooleanProp
(
false
),
/**
* 使用默认插槽时设置该选项
*/
useDefaultSlot
:
makeBooleanProp
(
false
),
/**
* 禁用
*/
disabled
:
makeBooleanProp
(
false
),
/**
* 只读
*/
readonly
:
makeBooleanProp
(
false
),
/**
* 选择器占位符
*/
placeholder
:
String
,
/**
* 弹出层标题
*/
title
:
String
,
/**
* 接收当前列的选中项 item、当前列下标、当前列选中项下标下一列数据处理函数 resolve、结束选择 finish
*/
columnChange
:
Function
as
PropType
<
ColPickerColumnChange
>
,
/**
* 自定义展示文案的格式化函数,返回一个字符串
*/
displayFormat
:
Function
as
PropType
<
ColPickerDisplayFormat
>
,
/**
* 确定前校验函数,接收 (value, resolve) 参数,通过 resolve 继续执行 picker,resolve 接收 1 个 boolean 参数
*/
beforeConfirm
:
Function
as
PropType
<
ColPickerBeforeConfirm
>
,
/**
* 选择器的值靠右展示
*/
alignRight
:
makeBooleanProp
(
false
),
/**
* 是否为错误状态,错误状态时右侧内容为红色
*/
error
:
makeBooleanProp
(
false
),
/**
* 是否必填
*/
required
:
makeBooleanProp
(
false
),
/**
* 设置选择器大小,可选值:large
*/
size
:
String
,
/**
* 选项对象中,value 对应的 key
*/
valueKey
:
makeStringProp
(
"value"
),
/**
* 选项对象中,展示的文本对应的 key
*/
labelKey
:
makeStringProp
(
"label"
),
/**
* 选项对象中,提示文案对应的 key
*/
tipKey
:
makeStringProp
(
"tip"
),
/**
* loading 图标的颜色
*/
loadingColor
:
makeStringProp
(
"#4D80F0"
),
/**
* 点击遮罩是否关闭
*/
closeOnClickModal
:
makeBooleanProp
(
true
),
/**
* 自动触发 column-change 事件来补全数据,当 columns 为空数组或者 columns 数组长度小于 value 数组长度时,会自动触发 column-change
*/
autoComplete
:
makeBooleanProp
(
false
),
/**
* 弹窗层级
*/
zIndex
:
makeNumberProp
(
15
),
/**
* 弹出面板是否设置底部安全距离(iphone X 类型的机型)
*/
safeAreaInsetBottom
:
makeBooleanProp
(
true
),
/**
* 是否超出隐藏
*/
ellipsis
:
makeBooleanProp
(
false
),
/**
* 表单域 model 字段名,在使用表单校验功能的情况下,该属性是必填的
*/
prop
:
String
,
/**
* 表单验证规则,结合wd-form组件使用
*/
rules
:
makeArrayProp
<
FormItemRule
>
(),
/**
* label 外部自定义样式
*/
customViewClass
:
makeStringProp
(
""
),
/**
* value 外部自定义样式
*/
customLabelClass
:
makeStringProp
(
""
),
customValueClass
:
makeStringProp
(
""
)
};
export
type
ColPickerProps
=
ExtractPropTypes
<
typeof
colPickerProps
>
;
export
type
ColPickerColumnChangeOption
=
{
selectedItem
:
Record
<
string
,
any
>
;
index
:
number
;
rowIndex
:
number
;
addMValue
:
Function
;
resolve
:
(
nextColumn
:
Record
<
string
,
any
>
[])
=>
void
;
finish
:
(
isOk
?:
boolean
)
=>
void
;
};
export
type
ColPickerColumnChange
=
(
option
:
ColPickerColumnChangeOption
)
=>
void
;
export
type
ColPickerDisplayFormat
=
(
selectedItems
:
Record
<
string
,
any
>
[])
=>
string
;
export
type
ColPickerBeforeConfirm
=
(
value
:
(
string
|
number
)[],
selectedItems
:
Record
<
string
,
any
>
[],
resolve
:
(
isPass
:
boolean
)
=>
void
)
=>
void
;
export
type
ColPickerExpose
=
{
// 关闭picker弹框
close
:
()
=>
void
;
// 打开picker弹框
open
:
()
=>
void
;
};
export
type
ColPickerInstance
=
ComponentPublicInstance
<
ColPickerExpose
,
ColPickerProps
>
;
src/components/wd-col-picker22/wd-col-picker.vue
deleted
100644 → 0
View file @
10eb7e7a
<
template
>
<view
:class=
"`wd-col-picker $
{cell.border.value ? 'is-border' : ''} ${customClass}`" :style="customStyle">
<view
class=
"wd-col-picker__field"
@
click=
"showPicker"
>
<slot
v-if=
"useDefaultSlot"
></slot>
<view
v-else
:class=
"`wd-col-picker__cell $
{disabled
&&
'is-disabled'} ${readonly
&&
'is-readonly'} ${
alignRight
&&
'is-align-right'
} ${error
&&
'is-error'} ${size
&&
'is-' + size}`"
>
<view
v-if=
"label || useLabelSlot"
:class=
"`wd-col-picker__label $
{isRequired
&&
'is-required'} ${customLabelClass}`"
:style="labelWidth ? 'min-width:' + labelWidth + ';max-width:' + labelWidth + ';' : ''"
>
<block
v-if=
"label"
>
{{
label
}}
</block>
<slot
v-else
name=
"label"
></slot>
</view>
<view
class=
"wd-col-picker__body"
>
<view
class=
"wd-col-picker__value-wraper"
>
<view
:class=
"`wd-col-picker__value $
{ellipsis
&&
'is-ellipsis'} ${customValueClass} ${
showValue ? '' : 'wd-col-picker__value--placeholder'
}`"
>
{{
showValue
||
placeholder
||
translate
(
"placeholder"
)
}}
</view>
<wd-icon
v-if=
"!disabled && !readonly"
custom-class=
"wd-col-picker__arrow"
name=
"arrow-right"
/>
</view>
<view
v-if=
"errorMessage"
class=
"wd-col-picker__error-message"
>
{{
errorMessage
}}
</view>
</view>
</view>
</view>
<wd-action-sheet
v-model=
"pickerShow"
:duration=
"250"
:title=
"title || translate('title')"
:close-on-click-modal=
"closeOnClickModal"
:z-index=
"zIndex"
:safe-area-inset-bottom=
"safeAreaInsetBottom"
@
open=
"handlePickerOpend"
@
close=
"handlePickerClose"
>
<view
class=
"flex-align-center tags"
>
<div
v-for=
"(item, index) in mValue"
:key=
"index"
type=
"primary"
>
{{
item
.
name
}}
</div>
</view>
<view
class=
"wd-col-picker__selected"
>
<scroll-view
:scroll-x=
"true"
scroll-with-animation
:scroll-left=
"scrollLeft"
>
<view
class=
"wd-col-picker__selected-container"
>
<view
v-for=
"(select, colIndex) in selectList"
:key=
"colIndex"
:class=
"`wd-col-picker__selected-item $
{colIndex === currentCol
&&
'is-selected'}`"
@click="handleColClick(colIndex)"
>
{{
selectShowList
[
colIndex
]
||
translate
(
"select"
)
}}
</view>
<view
class=
"wd-col-picker__selected-line"
:style=
"lineStyle"
></view>
</view>
</scroll-view>
</view>
<view
class=
"wd-col-picker__list-container"
>
<view
v-for=
"(col, colIndex) in selectList"
:key=
"colIndex"
class=
"wd-col-picker__list"
:style=
"colIndex === currentCol ? 'display: block;' : 'display: none;'"
>
<view
v-for=
"(item, index) in col"
:key=
"index"
:class=
"`wd-col-picker__list-item $
{item.disabled
&&
'is-disabled'} ${
mValue.some(v => v[valueKey] == item[valueKey])
&&
'is-selected'
}`"
@click="chooseItem(colIndex, index)"
>
<!-- $
{pickerColSelected[colIndex]
&&
item[valueKey] === pickerColSelected[colIndex]
&&
'is-selected'} -->
<view>
<view
class=
"wd-col-picker__list-item-label"
>
{{
item
[
labelKey
]
}}
</view>
<view
v-if=
"item[tipKey]"
class=
"wd-col-picker__list-item-tip"
>
{{
item
[
tipKey
]
}}
</view>
</view>
<wd-icon
custom-class=
"wd-col-picker__checked"
name=
"check"
></wd-icon>
</view>
<view
v-if=
"loading"
class=
"wd-col-picker__loading"
>
<wd-loading
:color=
"loadingColor"
/>
</view>
</view>
</view>
</wd-action-sheet>
</view>
</
template
>
<
script
lang=
"ts"
>
export
default
{
name
:
"col-picker"
,
options
:
{
addGlobalClass
:
true
,
virtualHost
:
true
,
styleIsolation
:
"shared"
}
};
</
script
>
<
script
lang=
"ts"
setup
>
import
{
computed
,
getCurrentInstance
,
onMounted
,
ref
,
watch
}
from
"vue"
;
import
{
debounce
,
getRect
,
isArray
,
isBoolean
,
isFunction
}
from
"wot-design-uni/components/common/util"
;
import
{
useCell
}
from
"wot-design-uni/components/composables/useCell"
;
import
{
FORM_KEY
,
type
FormItemRule
}
from
"wot-design-uni/components/wd-form/types"
;
import
{
useParent
}
from
"wot-design-uni/components/composables/useParent"
;
import
{
useTranslate
}
from
"wot-design-uni/components/composables/useTranslate"
;
import
{
colPickerProps
,
type
ColPickerExpose
}
from
"./types"
;
const
{
translate
}
=
useTranslate
(
"col-picker"
);
const
$container
=
".wd-col-picker__selected-container"
;
const
$item
=
".wd-col-picker__selected-item"
;
const
props
=
defineProps
(
colPickerProps
);
console
.
log
(
props
.
mMax
);
console
.
log
(
props
.
mValue
);
const
emit
=
defineEmits
([
"close"
,
"update:modelValue"
,
"update:mValue"
,
"confirm"
]);
const
pickerShow
=
ref
<
boolean
>
(
false
);
const
currentCol
=
ref
<
number
>
(
0
);
const
selectList
=
ref
<
Record
<
string
,
any
>
[][]
>
([]);
const
pickerColSelected
=
ref
<
(
string
|
number
)[]
>
([]);
const
selectShowList
=
ref
<
Record
<
string
,
any
>
[]
>
([]);
const
loading
=
ref
<
boolean
>
(
false
);
const
isChange
=
ref
<
boolean
>
(
false
);
const
lastSelectList
=
ref
<
Record
<
string
,
any
>
[][]
>
([]);
const
lastPickerColSelected
=
ref
<
(
string
|
number
)[]
>
([]);
const
lineStyle
=
ref
<
string
>
(
""
);
const
scrollLeft
=
ref
<
number
>
(
0
);
const
inited
=
ref
<
boolean
>
(
false
);
const
isCompleting
=
ref
<
boolean
>
(
false
);
const
{
proxy
}
=
getCurrentInstance
()
as
any
;
const
cell
=
useCell
();
const
updateLineAndScroll
=
debounce
(
function
(
animation
=
true
)
{
setLineStyle
(
animation
);
lineScrollIntoView
();
},
50
);
const
showValue
=
computed
(()
=>
{
const
selectedItems
=
(
props
.
modelValue
||
[]).
map
((
item
,
colIndex
)
=>
{
return
getSelectedItem
(
item
,
colIndex
,
selectList
.
value
);
});
if
(
props
.
displayFormat
)
{
return
props
.
displayFormat
(
selectedItems
);
}
else
{
return
selectedItems
.
map
(
item
=>
{
return
item
[
props
.
labelKey
];
})
.
join
(
""
);
}
});
watch
(
()
=>
props
.
modelValue
,
newValue
=>
{
if
(
newValue
===
pickerColSelected
.
value
)
return
;
pickerColSelected
.
value
=
newValue
;
newValue
.
map
((
item
,
colIndex
)
=>
{
return
getSelectedItem
(
item
,
colIndex
,
selectList
.
value
)[
props
.
labelKey
];
});
handleAutoComplete
();
},
{
deep
:
true
,
immediate
:
true
}
);
watch
(
()
=>
props
.
columns
,
(
newValue
,
oldValue
)
=>
{
if
(
newValue
.
length
&&
!
isArray
(
newValue
[
0
]))
{
console
.
error
(
"[wot design] error(wd-col-picker): the columns props of wd-col-picker should be a two-dimensional array"
);
return
;
}
if
(
newValue
.
length
===
0
&&
!
oldValue
)
return
;
const
newSelectedList
=
newValue
.
slice
(
0
);
selectList
.
value
=
newSelectedList
;
selectShowList
.
value
=
pickerColSelected
.
value
.
map
((
item
,
colIndex
)
=>
{
return
getSelectedItem
(
item
,
colIndex
,
newSelectedList
)[
props
.
labelKey
];
});
lastSelectList
.
value
=
newSelectedList
;
if
(
newSelectedList
.
length
>
0
)
{
currentCol
.
value
=
newSelectedList
.
length
-
1
;
}
},
{
deep
:
true
,
immediate
:
true
}
);
watch
(
()
=>
props
.
columnChange
,
fn
=>
{
if
(
fn
&&
!
isFunction
(
fn
))
{
console
.
error
(
"The type of columnChange must be Function"
);
}
},
{
deep
:
true
,
immediate
:
true
}
);
watch
(
()
=>
props
.
displayFormat
,
fn
=>
{
if
(
fn
&&
!
isFunction
(
fn
))
{
console
.
error
(
"The type of displayFormat must be Function"
);
}
},
{
deep
:
true
,
immediate
:
true
}
);
watch
(
()
=>
props
.
beforeConfirm
,
fn
=>
{
if
(
fn
&&
!
isFunction
(
fn
))
{
console
.
error
(
"The type of beforeConfirm must be Function"
);
}
},
{
deep
:
true
,
immediate
:
true
}
);
const
{
parent
:
form
}
=
useParent
(
FORM_KEY
);
// 表单校验错误信息
const
errorMessage
=
computed
(()
=>
{
if
(
form
&&
props
.
prop
&&
form
.
errorMessages
&&
form
.
errorMessages
[
props
.
prop
])
{
return
form
.
errorMessages
[
props
.
prop
];
}
else
{
return
""
;
}
});
// 是否展示必填
const
isRequired
=
computed
(()
=>
{
let
formRequired
=
false
;
if
(
form
&&
form
.
props
.
rules
)
{
const
rules
=
form
.
props
.
rules
;
for
(
const
key
in
rules
)
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
rules
,
key
)
&&
key
===
props
.
prop
&&
Array
.
isArray
(
rules
[
key
]))
{
formRequired
=
rules
[
key
].
some
((
rule
:
FormItemRule
)
=>
rule
.
required
);
}
}
}
return
props
.
required
||
props
.
rules
.
some
(
rule
=>
rule
.
required
)
||
formRequired
;
});
onMounted
(()
=>
{
inited
.
value
=
true
;
});
// 打开弹框
function
open
()
{
showPicker
();
}
// 关闭弹框
function
close
()
{
handlePickerClose
();
}
function
handlePickerOpend
()
{
updateLineAndScroll
(
false
);
}
function
handlePickerClose
()
{
pickerShow
.
value
=
false
;
// 如果目前用户正在选择,需要在popup关闭时将数据重置回上次数据,popup 关闭时间 250
if
(
isChange
.
value
)
{
setTimeout
(()
=>
{
selectList
.
value
=
lastSelectList
.
value
.
slice
(
0
);
pickerColSelected
.
value
=
lastPickerColSelected
.
value
.
slice
(
0
);
selectShowList
.
value
=
lastPickerColSelected
.
value
.
map
((
item
,
colIndex
)
=>
{
return
getSelectedItem
(
item
,
colIndex
,
lastSelectList
.
value
)[
props
.
labelKey
];
});
currentCol
.
value
=
lastSelectList
.
value
.
length
-
1
;
isChange
.
value
=
false
;
},
250
);
}
emit
(
"close"
);
}
function
showPicker
()
{
const
{
disabled
,
readonly
}
=
props
;
if
(
disabled
||
readonly
)
return
;
pickerShow
.
value
=
true
;
lastPickerColSelected
.
value
=
pickerColSelected
.
value
.
slice
(
0
);
lastSelectList
.
value
=
selectList
.
value
.
slice
(
0
);
}
function
getSelectedItem
(
value
:
string
|
number
,
colIndex
:
number
,
selectList
:
Record
<
string
,
any
>
[][])
{
const
{
valueKey
,
labelKey
}
=
props
;
if
(
selectList
[
colIndex
])
{
const
selecteds
=
selectList
[
colIndex
].
filter
(
item
=>
{
return
item
[
valueKey
]
===
value
;
});
if
(
selecteds
.
length
>
0
)
{
return
selecteds
[
0
];
}
}
return
{
[
valueKey
]:
value
,
[
labelKey
]:
""
};
}
function
chooseItem
(
colIndex
:
number
,
index
:
number
)
{
const
item
=
selectList
.
value
[
colIndex
][
index
];
if
(
item
.
disabled
)
return
;
const
newPickerColSelected
=
pickerColSelected
.
value
.
slice
(
0
,
colIndex
);
newPickerColSelected
.
push
(
item
[
props
.
valueKey
]);
isChange
.
value
=
true
;
pickerColSelected
.
value
=
newPickerColSelected
;
selectList
.
value
=
selectList
.
value
.
slice
(
0
,
colIndex
+
1
);
selectShowList
.
value
=
newPickerColSelected
.
map
((
item
,
colIndex
)
=>
{
return
getSelectedItem
(
item
,
colIndex
,
selectList
.
value
)[
props
.
labelKey
];
});
handleColChange
(
colIndex
,
item
,
index
);
}
function
handleColChange
(
colIndex
:
number
,
item
:
Record
<
string
,
any
>
,
index
:
number
,
callback
?:
()
=>
void
)
{
loading
.
value
=
true
;
const
{
columnChange
,
beforeConfirm
}
=
props
;
columnChange
&&
columnChange
({
selectedItem
:
item
,
index
:
colIndex
,
rowIndex
:
index
,
resolve
:
(
nextColumn
:
Record
<
string
,
any
>
[])
=>
{
if
(
!
isArray
(
nextColumn
))
{
console
.
error
(
"[wot design] error(wd-col-picker): the data of each column of wd-col-picker should be an array"
);
return
;
}
const
newSelectList
=
selectList
.
value
.
slice
(
0
);
newSelectList
[
colIndex
+
1
]
=
nextColumn
;
selectList
.
value
=
newSelectList
;
loading
.
value
=
false
;
currentCol
.
value
=
colIndex
+
1
;
updateLineAndScroll
(
true
);
if
(
typeof
callback
===
"function"
)
{
isCompleting
.
value
=
false
;
selectShowList
.
value
=
pickerColSelected
.
value
.
map
((
item
,
colIndex
)
=>
{
return
getSelectedItem
(
item
,
colIndex
,
selectList
.
value
)[
props
.
labelKey
];
});
callback
();
}
},
addMValue
:
value
=>
{
emit
(
"update:mValue"
,
[...
props
.
mValue
,
value
]);
},
finish
:
(
isOk
?:
boolean
)
=>
{
// 每设置展示数据回显
if
(
typeof
callback
===
"function"
)
{
loading
.
value
=
false
;
isCompleting
.
value
=
false
;
return
;
}
if
(
isBoolean
(
isOk
)
&&
!
isOk
)
{
loading
.
value
=
false
;
return
;
}
if
(
beforeConfirm
)
{
beforeConfirm
(
pickerColSelected
.
value
,
pickerColSelected
.
value
.
map
((
item
,
colIndex
)
=>
{
return
getSelectedItem
(
item
,
colIndex
,
selectList
.
value
);
}),
(
isPass
:
boolean
)
=>
{
if
(
isPass
)
{
onConfirm
();
}
else
{
loading
.
value
=
false
;
}
}
);
}
else
{
onConfirm
();
}
}
});
}
function
onConfirm
()
{
isChange
.
value
=
false
;
loading
.
value
=
false
;
pickerShow
.
value
=
false
;
emit
(
"update:modelValue"
,
pickerColSelected
.
value
);
emit
(
"confirm"
,
{
value
:
pickerColSelected
.
value
,
selectedItems
:
pickerColSelected
.
value
.
map
((
item
,
colIndex
)
=>
{
return
getSelectedItem
(
item
,
colIndex
,
selectList
.
value
);
})
});
}
function
handleColClick
(
index
:
number
)
{
isChange
.
value
=
true
;
currentCol
.
value
=
index
;
updateLineAndScroll
(
true
);
}
/**
* @description 更新navBar underline的偏移量
* @param {Boolean} animation 是否伴随动画
*/
function
setLineStyle
(
animation
=
true
)
{
if
(
!
inited
.
value
)
return
;
getRect
(
$item
,
true
,
proxy
).
then
(
rects
=>
{
const
rect
=
rects
[
currentCol
.
value
];
// const width = lineWidth || (slidableNum
<
items
.
length
?
rect
.
width
:
(
rect
.
width
-
14
))
const
width
=
16
;
let
left
=
rects
.
slice
(
0
,
currentCol
.
value
).
reduce
((
prev
:
any
,
curr
:
any
)
=>
prev
+
curr
.
width
,
0
);
left
+=
(
Number
(
rect
.
width
)
-
width
)
/
2
;
const
transition
=
animation
?
"transition: width 300ms ease, transform 300ms ease;"
:
""
;
const
lineStyleTemp
=
`
transform: translateX(
${
left
}
px);
${
transition
}
`
;
// 防止重复绘制
if
(
lineStyle
.
value
!==
lineStyleTemp
)
{
lineStyle
.
value
=
lineStyleTemp
;
}
});
}
/**
* @description scroll-view滑动到active的tab_nav
*/
function
lineScrollIntoView
()
{
if
(
!
inited
.
value
)
return
;
Promise
.
all
([
getRect
(
$item
,
true
,
proxy
),
getRect
(
$container
,
false
,
proxy
)]).
then
(([
navItemsRects
,
navRect
])
=>
{
if
(
!
isArray
(
navItemsRects
)
||
navItemsRects
.
length
===
0
)
return
;
// 选中元素
const
selectItem
=
navItemsRects
[
currentCol
.
value
];
// 选中元素之前的节点的宽度总和
const
offsetLeft
=
navItemsRects
.
slice
(
0
,
currentCol
.
value
).
reduce
((
prev
,
curr
)
=>
prev
+
Number
(
curr
.
width
),
0
);
// scroll-view滑动到selectItem的偏移量
scrollLeft
.
value
=
offsetLeft
-
((
navRect
as
any
).
width
-
Number
(
selectItem
.
width
))
/
2
;
});
}
// 递归列数据补齐
function
diffColumns
(
colIndex
:
number
)
{
// colIndex 为 -1 时,item 为空对象,>=0 时则具有 value 属性
const
item
=
colIndex
===
-
1
?
{}
:
{
[
props
.
valueKey
]:
props
.
modelValue
[
colIndex
]
};
handleColChange
(
colIndex
,
item
,
-
1
,
()
=>
{
// 如果 columns 长度还小于 value 长度,colIndex + 1,继续递归补齐
if
(
selectList
.
value
.
length
<
props
.
modelValue
.
length
)
{
diffColumns
(
colIndex
+
1
);
}
});
}
function
handleAutoComplete
()
{
if
(
props
.
autoComplete
)
{
// 如果 columns 数组长度为空,或者长度小于 value 的长度,自动触发 columnChange 来补齐数据
if
(
selectList
.
value
.
length
<
props
.
modelValue
.
length
||
selectList
.
value
.
length
===
0
)
{
// isCompleting 是否在自动补全,锁操作
if
(
!
isCompleting
.
value
)
{
// 如果 columns 长度为空,则传入的 colIndex 为 -1
const
colIndex
=
selectList
.
value
.
length
===
0
?
-
1
:
selectList
.
value
.
length
-
1
;
diffColumns
(
colIndex
);
}
isCompleting
.
value
=
true
;
}
}
}
defineExpose
<
ColPickerExpose
>
({
close
,
open
});
</
script
>
<
style
lang=
"scss"
scoped
>
@import
"./index.scss"
;
</
style
>
src/pages/recommend/releasePostion/step1.vue
View file @
373a242f
...
@@ -6,9 +6,35 @@
...
@@ -6,9 +6,35 @@
<view
class=
"t2"
>
选择对应的职位并填写职位信息
</view>
<view
class=
"t2"
>
选择对应的职位并填写职位信息
</view>
</view>
</view>
<view
class=
"content"
>
<view
class=
"content"
>
<view
class=
"switch"
>
<selectbox
:options=
"typeOptions"
v-model=
"typeValue"
></selectbox>
<!--
<view
class=
"active"
>
全职
</view>
<form-row>
<view>
兼职
</view>
-->
<form-item
title=
"职位类型"
>
<wd-col-picker
v-model=
"value"
:columns=
"columns"
:column-change=
"columnChange"
@
confirm=
"handleConfirm"
label-key=
"name"
value-key=
"id"
use-default-slot
>
<view
:class=
"`inner flex-between $
{pinias.formData.jobTypeText ? '' : 'placeholder'}`">
{{
pinias
.
formData
.
jobTypeText
||
"请选择职位类型"
}}
</view>
</wd-col-picker>
</form-item>
</form-row>
<form-row>
<form-item
title=
"职位标题"
icon=
"edit"
>
<input
type=
"text"
placeholder=
"输入职位标题如“财务总监”"
/>
</form-item>
</form-row>
<form-row>
<form-item
title=
"职位描述"
:border=
"false"
icon=
""
>
<textarea></textarea>
</form-item>
</form-row>
<!--
<view
class=
"switch"
>
<view
<view
v-for=
"(item, index) in EnumWorkMode"
v-for=
"(item, index) in EnumWorkMode"
:class=
"item.code == pinias.formData.workMode ? 'active' : ''"
:class=
"item.code == pinias.formData.workMode ? 'active' : ''"
...
@@ -16,8 +42,8 @@
...
@@ -16,8 +42,8 @@
:key=
"index"
:key=
"index"
>
{{
item
.
text
}}
>
{{
item
.
text
}}
</view>
</view>
</view>
</view>
-->
<view
class=
"form-item"
>
<
!--
<
view
class=
"form-item"
>
<view
class=
"form-item-title"
>
职位类型
</view>
<view
class=
"form-item-title"
>
职位类型
</view>
<wd-col-picker
<wd-col-picker
v-model=
"value"
v-model=
"value"
...
@@ -33,8 +59,8 @@
...
@@ -33,8 +59,8 @@
<view
class=
"arrow"
></view>
<view
class=
"arrow"
></view>
</view>
</view>
</wd-col-picker>
</wd-col-picker>
</view>
</view>
-->
<view
class=
"form-item"
>
<
!--
<
view
class=
"form-item"
>
<view
class=
"form-item-title"
>
职位标题
</view>
<view
class=
"form-item-title"
>
职位标题
</view>
<view
class=
"inner flex-between"
>
<view
class=
"inner flex-between"
>
<input
<input
...
@@ -44,8 +70,8 @@
...
@@ -44,8 +70,8 @@
placeholder=
"请输入职业标题"
placeholder=
"请输入职业标题"
/>
/>
</view>
</view>
</view>
</view>
-->
<view
class=
"form-item describe"
style=
"border: 0"
>
<
!--
<
view
class=
"form-item describe"
style=
"border: 0"
>
<view
class=
"form-item-title"
>
职位描述
</view>
<view
class=
"form-item-title"
>
职位描述
</view>
<wd-textarea
<wd-textarea
custom-class=
"textarea"
custom-class=
"textarea"
...
@@ -54,12 +80,9 @@
...
@@ -54,12 +80,9 @@
v-model=
"pinias.formData.jobDesc"
v-model=
"pinias.formData.jobDesc"
placeholder=
"请输入你的职位描述"
placeholder=
"请输入你的职位描述"
/>
/>
</view>
</view>
-->
</view>
</view>
<!--
<view
class=
"btn-wrap"
>
<button
class=
"bottom-btn"
@
tap=
"next"
>
下一步
</button>
</view>
-->
<wd-tabbar
<wd-tabbar
@
tap=
"next"
@
tap=
"next"
custom-style=
"display: flex;justify-content: center !important;z-index:1;"
custom-style=
"display: flex;justify-content: center !important;z-index:1;"
...
@@ -81,6 +104,10 @@ import { validateForm } from "@/utils/utils";
...
@@ -81,6 +104,10 @@ import { validateForm } from "@/utils/utils";
import
_
from
"lodash"
;
import
_
from
"lodash"
;
import
{
useReleasePostionStore
}
from
"./store"
;
import
{
useReleasePostionStore
}
from
"./store"
;
import
FormItem
from
"@/components/form/form-item.vue"
;
import
FormRow
from
"@/components/form/form-row.vue"
;
import
Selectbox
from
"@/components/form/selectbox.vue"
;
const
pinias
=
useReleasePostionStore
();
const
pinias
=
useReleasePostionStore
();
onLoad
(
option
=>
{
onLoad
(
option
=>
{
...
@@ -139,11 +166,33 @@ const next = () => {
...
@@ -139,11 +166,33 @@ const next = () => {
});
});
}
}
};
};
/* 类型 */
const
typeValue
=
ref
(
1
);
const
typeOptions
=
[
{
label
:
"全职"
,
value
:
1
},
{
label
:
"兼职"
,
value
:
2
},
{
label
:
"见习"
,
value
:
3
},
{
label
:
"实习"
,
value
:
4
}
];
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
@import
"./common.scss"
;
@import
"./common.scss"
;
.describe
{
/* .describe {
textarea {
textarea {
box-sizing: border-box;
box-sizing: border-box;
width: 686rpx;
width: 686rpx;
...
@@ -156,21 +205,20 @@ const next = () => {
...
@@ -156,21 +205,20 @@ const next = () => {
}
}
.page {
.page {
.textarea {
.textarea {
max-height: 272rpx;
margin-top: 32rpx;
margin-top: 32rpx;
background: #f2f5fb;
background: #f2f5fb;
max-height
:
272rpx
;
:deep(.wd-textarea__value) {
:deep(.wd-textarea__value) {
background
:
#f2f5fb
!
important
;
max-height
:
272rpx
;
width: 100%;
width: 100%;
max-height: 272rpx;
padding: 0 !important;
padding: 0 !important;
background: #f2f5fb !important;
}
}
:deep(.wd-textarea__count) {
:deep(.wd-textarea__count) {
background: none !important;
background: none !important;
}
}
}
}
}
}
.switch {
.switch {
display: flex;
display: flex;
align-items: center;
align-items: center;
...
@@ -189,8 +237,14 @@ const next = () => {
...
@@ -189,8 +237,14 @@ const next = () => {
background-color: #1f86ff;
background-color: #1f86ff;
}
}
}
}
} */
textarea
{
box-sizing
:
border-box
;
width
:
100%
;
padding
:
32rpx
;
background
:
#f2f5fb
;
border-radius
:
8rpx
;
}
}
.foot-btn
{
.foot-btn
{
position
:
fixed
;
position
:
fixed
;
display
:
flex
;
display
:
flex
;
...
...
src/pages/recommend/releasePostion/step2.vue
View file @
373a242f
...
@@ -36,7 +36,7 @@
...
@@ -36,7 +36,7 @@
<wd-icon
@
click=
"handleClose"
name=
"close"
size=
"30rpx"
></wd-icon>
<wd-icon
@
click=
"handleClose"
name=
"close"
size=
"30rpx"
></wd-icon>
</view>
</view>
<wd-picker-view
@
change=
"handleConfirm"
use-default-slot
:columns=
"columns"
v-model=
"value"
></wd-picker-view>
<wd-picker-view
@
change=
"handleConfirm"
use-default-slot
:columns=
"columns"
v-model=
"value"
></wd-picker-view>
<view
style=
"
width: 100%; display: flex; justify-content: center
"
<view
style=
"
display: flex; justify-content: center; width: 100%
"
><wd-button
style=
"width: 80%"
@
click=
"handleClose"
block
:round=
"false"
>
确定
</wd-button></view
><wd-button
style=
"width: 80%"
@
click=
"handleClose"
block
:round=
"false"
>
确定
</wd-button></view
>
>
</wd-popup>
</wd-popup>
...
@@ -283,11 +283,11 @@ initViewData();
...
@@ -283,11 +283,11 @@ initViewData();
border-radius
:
50%
!
important
;
border-radius
:
50%
!
important
;
}
}
.title-box
{
.title-box
{
box-sizing
:
border-box
;
display
:
flex
;
display
:
flex
;
align-items
:
center
;
align-items
:
center
;
justify-content
:
space-between
;
justify-content
:
space-between
;
padding
:
0
32rpx
;
padding
:
0
32rpx
;
box-sizing
:
border-box
;
}
}
.welfare
{
.welfare
{
display
:
flex
;
display
:
flex
;
...
@@ -339,7 +339,6 @@ picker-view {
...
@@ -339,7 +339,6 @@ picker-view {
justify-content
:
space-around
;
justify-content
:
space-around
;
color
:
#cccccc
;
color
:
#cccccc
;
}
}
.foot-btn
{
.foot-btn
{
position
:
fixed
;
position
:
fixed
;
display
:
flex
;
display
:
flex
;
...
...
src/pages/recommend/releasePostion/step4.vue
View file @
373a242f
...
@@ -172,7 +172,6 @@ initViewData();
...
@@ -172,7 +172,6 @@ initViewData();
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
@import
"./common.scss"
;
@import
"./common.scss"
;
.foot-btn
{
.foot-btn
{
position
:
fixed
;
position
:
fixed
;
display
:
flex
;
display
:
flex
;
...
...
src/static/image/icon/arrow.png
0 → 100644
View file @
373a242f
434 Bytes
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment