[update] 修改企标立项、变更流程

This commit is contained in:
lideqin
2023-12-05 16:07:09 +08:00
parent 160bc64235
commit bc870e5f9e
15 changed files with 1750 additions and 259 deletions
+1 -18
View File
@@ -4,6 +4,7 @@
<van-field
readonly
clickable
type="text"
name="calendar"
:value="value"
v-bind="$attrs"
@@ -13,8 +14,6 @@
<van-calendar
color="#3074F6"
v-model="showCalendar"
:min-date="minDate"
:max-date="maxDate"
@confirm="onConfirm"
/>
</div>
@@ -25,22 +24,6 @@
export default {
name: 'CalendarField',
props: {
// 可选择的最小日期--不知道为什么没有起作用
minDate: {
// type: [Date, String],
required: false,
default: () => {
return new Date(2020, 0, 1)
}
},
// 可选择的最大日期--不知道为什么没有起作用
maxDate: {
type: [Date, String],
required: false,
default: () => {
return new Date(2030, 12, 31)
}
},
value: {
type: [String, Number, Object],
required: false
+268
View File
@@ -0,0 +1,268 @@
<template>
<ul class="list-menu" v-if="data.length">
<!-- @click.stop="!item.isLeaf || selectItem(item.value)"-->
<li v-for="(item, i) in data" :key="i" @click.stop="selectItem(item.value)" v-show="expandFlag">
<div class="item">
<div class="item-left">
<!-- 展开的图标 -->
<i class='expandIcon'
@click.stop="expandItem(item, i)"
:class="[expandArr.includes(i) ? 'reduce' : 'add',item.children && item.children.length ? '' : 'disabled']">
</i>
<!-- 选项名 -->
<span class="value-span">{{ item.title }}</span>
</div>
<!-- 选择的图标 -->
<!-- 单选 -->
<template v-if="!multiple">
<i class='selectIcon'
:class="[value === item.value ? 'checked' : 'noChecked']">
</i>
</template>
<!-- 多选 -->
<template v-else>
<i class='selectIcon multiple-select-icon'
:class="[checkedArr.includes(item.value) ? 'checked' : 'noChecked']">
</i>
</template>
<!-- <i class='selectIcon'-->
<!-- :class="[checkedArr.indexOf(item.value) > -1 ? 'checked' : 'noChecked']">-->
<!-- </i>-->
</div>
<select-department
v-if='item.children'
@input='input'
:data='item.children'
:valueKey='valueKey'
:labelKey='labelKey'
:value="value"
:toastText='toastText'
:expandFlag='expandArr.includes(i)'
:multiple="multiple"
/>
</li>
</ul>
</template>
<script>
export default {
name: 'SelectDepartment',
props: {
// 选中的值的属性名,必传
valueKey: String,
// 在页面要展示的选项属性名,必传
labelKey: String,
// 选中的值,必传
value: [Object, String, Array],
// 控制展开,不需要传
expandFlag: {
type: Boolean,
default: true
},
// 总数据,必传
data: Array,
// 不可选提示文字,非必传
toastText: String,
// 是否多选
multiple: {
type: Boolean,
default: false
}
},
watch: {
value: {
immediate: true,
deep: true,
handler (val) {
if (this.multiple !== false) {
this.checkedArr = this.value
}
return val
}
}
},
data () {
return {
// 当前级组件已展开的项
expandArr: [],
checkedArr: []
}
},
methods: {
// 子组件逐级传递选中项
input (item) {
// console.log(item.concat(this.checkedArr))
if (!this.multiple) {
// 是单选
this.$emit('input', item)
} else {
this.$emit('input', item)
}
},
// 选择
selectItem (item) {
console.log(item)
// this.$emit('input', item)
if (!this.multiple) {
// 是单选
this.$emit('input', item)
} else {
this.checkedArr.indexOf(item) <= -1 ? this.checkedArr.push(item) : this.checkedArr.splice(this.checkedArr.indexOf(item), 1)
this.$emit('input', this.checkedArr)
}
},
// 展开
expandItem (item, i) {
if (item.children && item.children.length) {
const index = this.expandArr.indexOf(i)
if (index > -1) {
this.expandArr.splice(index, 1)
} else {
this.expandArr.push(i)
}
}
}
},
created () {
}
}
</script>
<style scoped lang="less">
@import '~@assets/less/common.less';
.popup-box > ul {
padding-right: @pad-base;
}
ul {
width: 100%;
color: #2a2a2a;
font-size: 0.22rem;
background: #fff;
border-bottom: .8px solid #e1e1e1;
li {
.item {
padding: @pad-base;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
font-size: 0.3rem;
&-left {
display: flex;
flex: 1;
}
.expandIcon {
height: 0.4rem;
width: 0.4rem;
font-style: normal;
position: relative;
&:after {
position: absolute;
top: 50%;
left: 50%;
font-size: 0.4rem;
transform: translate(-50%, -50%);
}
&.add {
border-color: #2a2a2a;
&:after {
color: #2a2a2a;
content: '';
}
}
&.reduce {
border-color: @primary-color;
&:after {
color: @primary-color;
content: '';
}
}
&.disabled {
border-color: #ddd;
&:after {
color: #ddd;
}
}
}
.value-span {
text-align: left;
flex: 1;
}
.selectIcon {
float: right;
height: 0.3rem;
width: 0.3rem;
border: 1.5px solid;
border-radius: 50%;
position: relative;
&:after {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
&.checked {
border-color: @primary-color;
background: @primary-color;;
&:after {
color: #fff;
content: '✓';
}
}
&.noChecked {
border-color: @primary-color;
}
&.disabled {
border-color: #ddd;
}
}
.multiple-select-icon {
border-radius: 0.04rem;
}
}
&:not(:first-child) {
border-top: .8px solid #e1e1e1;
}
> ul {
border-bottom: 0;
padding-left: 0.35rem;
box-sizing: border-box;
li {
.item {
padding-left: 0.35rem;
box-sizing: border-box;
}
.item-left span{
width: 0;
overflow: auto;
}
border-top: .8px solid #e1e1e1;
}
}
}
}
</style>
+273
View File
@@ -0,0 +1,273 @@
<template>
<div>
<van-field
:class="(required ? 'required ' : '') + 'form-item label-weight'"
type="textarea"
:label="label"
clearable
@click="showPopup"
v-model="departmentNames"
:rules="rules"
rows="1"
autosize
:placeholder="$t('clickSelect') + label"
readonly
/>
<!-- 多选选择责任单位 -->
<van-popup v-if="multiple" v-model="showSelectDepartment" style="height: 60vh" position="bottom" safe-area-inset-bottom
:close-on-click-overlay="false" :close-on-popstate="true">
<div class="popup-box">
<div class="operate">
<span @click="selectDepartmentCancel">取消</span>
<span @click="selectDepartmenthandleOk">确认</span>
</div>
<select-department :data="list" :value="selectedDepartTemp" @input="selected" :multiple="true"></select-department>
</div>
</van-popup>
<!-- 单选选择责任单位 -->
<van-popup v-else v-model="showSelectDepartment" style="height: 60vh" position="bottom" safe-area-inset-bottom
:close-on-click-overlay="false" :close-on-popstate="true">
<div class="popup-box">
<div class="operate">
<span @click="selectDepartmentCancel">取消</span>
<span @click="singleSelectDepartmentHandleOk">确认</span>
</div>
<select-department :data="list" :value="singleSelectedDepartTemp" @input="selected" :multiple="false"></select-department>
</div>
<!-- <link-menu :data="list" value-key="value" label-key="title" :value="singleSelectedDepartTemp" @input="selected"></link-menu>-->
</van-popup>
</div>
</template>
<script>
import SelectDepartment from './SelectDepartment'
export default {
name: 'SelectDepartmentField',
components: { SelectDepartment },
props: {
readonly: {
type: Boolean,
required: false,
default: false
},
value: {
type: String,
required: true,
default: () => ''
},
list: {
type: Array,
default: () => []
},
departmentNameString: {
type: String,
default: () => ''
},
// 是否是多选,默认是多选
multiple: {
type: Boolean,
required: false,
default: false
},
// 是否必填
required: {
type: Boolean,
required: false,
default: false
},
// 校验信息
rules: {
type: [Array, null],
required: false,
default: null
},
label: {
type: String,
required: false,
default: '部门'
}
},
watch: {
departmentNameString: {
immediate: true,
deep: true,
handler (val) {
this.departmentNames = val
return val
}
},
value: {
immediate: true,
deep: true,
handler (val) {
if (val) {
console.log('测试初始化名字', val)
if (this.multiple) {
this.selectedDepartmentName = []
// 设置输入框中的显示
setTimeout(() => {
for (const item of val.split(',')) {
this.selectTitleByValue(item, this.list)
}
this.departmentNames = this.selectedDepartmentName.join(',')
}, 500)
} else {
// 设置输入框中的显示
setTimeout(() => {
this.departmentNames = this.getTitle(val, this.list)
}, 500)
}
} else {
// 说明传进来的是空
this.departmentNames = ''
}
return val
}
}
},
data () {
return {
rulesObj: {
departmentId: [{ required: true, message: '请选择责任单位' }]
},
showSelectDepartment: false, // 下方选择框是否显示
selectedDepartTemp: [], // 多选选中的部门暂存
confirm: false, // 是否点击了确认
selectedDepartmentName: [], // 多选时返回的名称数组
departmentNames: '', // 责任单位名称字符串,输入框中要展示的
singleSelectedDepartTemp: undefined// 单选选中的部门暂存
}
},
methods: {
// 查询传入的value在传入的数组中是否存在,存在返回title属性值
selectTitleByValue (value, arr) {
for (const item of arr) {
if (item.value === value) {
console.log(item.title)
// 说明找到了,返回item.title
// callback(item.title)
this.selectedDepartmentName.push(item.title)
break
}
// 没有找到,如果有子树,在子树中查找
if (item.children) {
this.selectTitleByValue(value, item.children)
}
}
// 循环结束还没有找到
// return title
},
// 点击选择框中的取消
selectDepartmentCancel () {
this.showSelectDepartment = false
},
// 多选责任部门点击确认
selectDepartmenthandleOk () {
// this.$emit('input',this.selectedDepartTemp)
// this.departmentNames = this.selectedDepartTemp.join(',')
// 设置列表不展示
this.showSelectDepartment = false
// 清空已选择的责任单位名称数组
this.selectedDepartmentName = []
for (const item of this.selectedDepartTemp) {
this.selectTitleByValue(item, this.list)
}
// 设置输入框中的显示
this.departmentNames = this.selectedDepartmentName.join(',')
// 设置输入框的绑定值
this.$emit('input', this.selectedDepartTemp.join(','))
},
// 点击选择,展示选择框
showPopup () {
if (this.readonly) {
return
}
console.log(this.value)
if (this.multiple) {
console.log(Boolean(this.value))
// 是多选
this.selectedDepartTemp = JSON.parse(JSON.stringify(this.value !== '' && this.value ? this.value.split(',') : []))
} else {
// 是单选
this.singleSelectedDepartTemp = this.value || undefined
}
this.showSelectDepartment = true
},
// 选择完成的回调
selected (val) {
if (this.multiple) {
// 是多选
this.selectedDepartTemp = JSON.parse(JSON.stringify(val))
} else {
// 是单选
this.singleSelectedDepartTemp = val
}
},
// 单选责任部门确认
singleSelectDepartmentHandleOk () {
// 设置输入框中的显示
this.departmentNames = this.getTitle(this.singleSelectedDepartTemp, this.list)
// 设置输入框的绑定值
this.$emit('input', this.singleSelectedDepartTemp)
// 设置列表不展示
this.showSelectDepartment = false
},
// 从传入的数组中查找传入值的title
getTitle (value, arr) {
let result = {}
arr.forEach(item => {
const loop = data => {
if (data.value === value) {
result = data
console.log(item.title)
return item.title
}
const child = data.children
if (child) {
for (let i = 0; i < child.length; i++) {
loop(child[i])
}
}
}
loop(item)
})
return result.title
}
}
}
</script>
<style scoped lang="less">
@import '~@assets/less/common.less';
// 解决线上滚动条不灵敏的bug
.popup-box{
height: 100%;
position: relative;
/deep/& > .list-menu {
height: calc(100% - 0.8rem);
overflow: auto;
}
}
.operate {
padding: 0 @pad-base;
box-sizing: border-box;
font-size: 0.3rem;
font-weight: 600;
height: 0.8rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.content {
width: 100%;
flex: 1;
}
</style>
+13 -1
View File
@@ -7,10 +7,10 @@
readonly
rows="1"
autosize
:rules="rules"
type="textarea"
@click="handleSelect"
>
</van-field>
<select-user
ref="evaluatePersonSelectedList"
@@ -67,6 +67,12 @@ export default {
type: String,
required: false,
default: ''
},
// 校验信息
rules: {
type: [Array, null],
required: false,
default: null
}
},
watch: {
@@ -76,6 +82,12 @@ export default {
handler (val) {
this.selectedDataNames = val
}
},
rules: {
immediate: true,
handler (val) {
console.log(val)
}
}
},
data () {
+4 -1
View File
@@ -7,6 +7,9 @@
clearable
@click="showPopup"
v-model="showValue"
rows="1"
autosize
type="textarea"
/>
<van-popup
v-model="show"
@@ -45,7 +48,7 @@ export default {
},
props: {
value: {
type: [Object, Array],
type: [Object, Array, String],
required: true,
default: () => []
},