|
|
@@ -0,0 +1,324 @@
|
|
|
+<template>
|
|
|
+ <div class="service-info">
|
|
|
+ <div class="main-content">
|
|
|
+ <div class="service-title">
|
|
|
+ <img class="label-icon" src="@/assets/img/home/label-icon.png" alt="">
|
|
|
+ 服务信息
|
|
|
+ </div>
|
|
|
+ <div class="service-content">
|
|
|
+ <div class="service-item">
|
|
|
+ <div class="sub-title">服务作物</div>
|
|
|
+ <div class="tag-group" v-if="!isEdit">
|
|
|
+ <div class="tag-item" v-for="(item, idx) in crops" :key="'c-'+idx">{{ item.name }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="tag-group add-tag-group" v-else>
|
|
|
+ <div class="tag-item" :class="{ self: item.isSelf === 1 }" v-for="(item, idx) in crops" :key="'ce-'+idx">
|
|
|
+ <span class="text">{{ item.name }}<el-icon @click.stop="handleEdit(item.name, 'crops')" v-if="item.isSelf===1" class="edit-icon"><Edit /></el-icon></span>
|
|
|
+ <el-icon v-if="item.isSelf===1" class="del-icon" @click.stop="handleDelete('crops', idx)"><Close /></el-icon>
|
|
|
+ </div>
|
|
|
+ <div class="tag-item last-add" @click="handleAdd('作物')"><el-icon class="add-icon"><Plus /></el-icon>作物</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="service-item">
|
|
|
+ <div class="sub-title">服务类型</div>
|
|
|
+ <div class="tag-group" v-if="!isEdit">
|
|
|
+ <div class="tag-item" v-for="(item, idx) in serviceTypes" :key="'t-'+idx">{{ item.name }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="tag-group add-tag-group" v-else>
|
|
|
+ <div class="tag-item" :class="{ self: item.isSelf === 1 }" v-for="(item, idx) in serviceTypes" :key="'te-'+idx">
|
|
|
+ <span class="text">{{ item.name }}<el-icon @click.stop="handleEdit(item.name, 'serviceTypes')" v-if="item.isSelf===1" class="edit-icon"><Edit /></el-icon></span>
|
|
|
+ <el-icon v-if="item.isSelf===1" class="del-icon" @click.stop="handleDelete('serviceTypes', idx)"><Close /></el-icon>
|
|
|
+ </div>
|
|
|
+ <div class="tag-item last-add" @click="handleAdd('类型')"><el-icon class="add-icon"><Plus /></el-icon>类型</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="service-item">
|
|
|
+ <div class="sub-title">农机设备</div>
|
|
|
+ <div class="tag-group" v-if="!isEdit">
|
|
|
+ <div class="tag-item" v-for="(item, idx) in machines" :key="'m-'+idx">{{ item.name }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="tag-group add-tag-group" v-else>
|
|
|
+ <div class="tag-item" :class="{ self: item.isSelf === 1 }" v-for="(item, idx) in machines" :key="'me-'+idx">
|
|
|
+ <span class="text">{{ item.name }}<el-icon @click.stop="handleEdit(item.name, 'machines')" v-if="item.isSelf===1" class="edit-icon"><Edit /></el-icon></span>
|
|
|
+ <el-icon v-if="item.isSelf===1" class="del-icon" @click.stop="handleDelete('machines', idx)"><Close /></el-icon>
|
|
|
+ </div>
|
|
|
+ <div class="tag-item last-add" @click="handleAdd('设备')"><el-icon class="add-icon"><Plus /></el-icon>设备</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <popup class="add-tag-popup" round v-model:show="showAddPopup">
|
|
|
+ <div class="popup-title" v-if="isEditPopup">编辑标签</div>
|
|
|
+ <div class="popup-title" v-else>添加{{addTypeName}}<span class="ml-2">标签</span></div>
|
|
|
+ <el-input class="popup-input" v-model="input" placeholder="标签" size="large" />
|
|
|
+ <div class="popup-button">
|
|
|
+ <div class="cancel" @click="showAddPopup = false">取消</div>
|
|
|
+ <div @click="handleConfirm">{{isEditPopup ? '确定' : '添加'}}</div>
|
|
|
+ </div>
|
|
|
+ </popup>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref } from "vue";
|
|
|
+import { Popup } from "vant";
|
|
|
+import { Edit, Close, Plus } from '@element-plus/icons-vue'
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ crops: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ serviceTypes: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ machines: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ isEdit: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+const emit = defineEmits(['update:crops', 'update:serviceTypes', 'update:machines', 'update:isEdit']);
|
|
|
+
|
|
|
+const showAddPopup = ref(false);
|
|
|
+const input = ref("");
|
|
|
+const addTypeName = ref("");
|
|
|
+const isEditPopup = ref(false);
|
|
|
+const currentCategory = ref('');
|
|
|
+const currentEditIndex = ref(-1);
|
|
|
+const currentEditName = ref('');
|
|
|
+
|
|
|
+function handleAdd(type) {
|
|
|
+ isEditPopup.value = false;
|
|
|
+ addTypeName.value = type;
|
|
|
+ input.value = "";
|
|
|
+ showAddPopup.value = true;
|
|
|
+ // 根据类型设置当前分类
|
|
|
+ if (type === '作物') {
|
|
|
+ currentCategory.value = 'crops';
|
|
|
+ } else if (type === '类型') {
|
|
|
+ currentCategory.value = 'serviceTypes';
|
|
|
+ } else if (type === '设备') {
|
|
|
+ currentCategory.value = 'machines';
|
|
|
+ }
|
|
|
+ currentEditIndex.value = -1;
|
|
|
+}
|
|
|
+
|
|
|
+function handleDelete(category, index) {
|
|
|
+ if (category === 'crops') {
|
|
|
+ const newCrops = [...props.crops];
|
|
|
+ newCrops.splice(index, 1);
|
|
|
+ emit('update:crops', newCrops);
|
|
|
+ }
|
|
|
+ if (category === 'serviceTypes') {
|
|
|
+ const newServiceTypes = [...props.serviceTypes];
|
|
|
+ newServiceTypes.splice(index, 1);
|
|
|
+ emit('update:serviceTypes', newServiceTypes);
|
|
|
+ }
|
|
|
+ if (category === 'machines') {
|
|
|
+ const newMachines = [...props.machines];
|
|
|
+ newMachines.splice(index, 1);
|
|
|
+ emit('update:machines', newMachines);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function handleEdit(val, category) {
|
|
|
+ isEditPopup.value = true;
|
|
|
+ input.value = val;
|
|
|
+ showAddPopup.value = true;
|
|
|
+ currentCategory.value = category;
|
|
|
+ currentEditName.value = val;
|
|
|
+ // 找到对应的索引
|
|
|
+ let targetArray = [];
|
|
|
+ if (category === 'crops') {
|
|
|
+ targetArray = props.crops;
|
|
|
+ } else if (category === 'serviceTypes') {
|
|
|
+ targetArray = props.serviceTypes;
|
|
|
+ } else if (category === 'machines') {
|
|
|
+ targetArray = props.machines;
|
|
|
+ }
|
|
|
+ currentEditIndex.value = targetArray.findIndex(item => item.name === val && item.isSelf === 1);
|
|
|
+}
|
|
|
+
|
|
|
+function handleConfirm() {
|
|
|
+ if (!input.value.trim()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isEditPopup.value && currentEditIndex.value >= 0) {
|
|
|
+ // 编辑模式
|
|
|
+ if (currentCategory.value === 'crops') {
|
|
|
+ const newCrops = [...props.crops];
|
|
|
+ newCrops[currentEditIndex.value].name = input.value.trim();
|
|
|
+ emit('update:crops', newCrops);
|
|
|
+ } else if (currentCategory.value === 'serviceTypes') {
|
|
|
+ const newServiceTypes = [...props.serviceTypes];
|
|
|
+ newServiceTypes[currentEditIndex.value].name = input.value.trim();
|
|
|
+ emit('update:serviceTypes', newServiceTypes);
|
|
|
+ } else if (currentCategory.value === 'machines') {
|
|
|
+ const newMachines = [...props.machines];
|
|
|
+ newMachines[currentEditIndex.value].name = input.value.trim();
|
|
|
+ emit('update:machines', newMachines);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 添加模式
|
|
|
+ const newItem = { name: input.value.trim(), isSelf: 1 };
|
|
|
+ if (currentCategory.value === 'crops') {
|
|
|
+ const newCrops = [...props.crops, newItem];
|
|
|
+ emit('update:crops', newCrops);
|
|
|
+ } else if (currentCategory.value === 'serviceTypes') {
|
|
|
+ const newServiceTypes = [...props.serviceTypes, newItem];
|
|
|
+ emit('update:serviceTypes', newServiceTypes);
|
|
|
+ } else if (currentCategory.value === 'machines') {
|
|
|
+ const newMachines = [...props.machines, newItem];
|
|
|
+ emit('update:machines', newMachines);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ showAddPopup.value = false;
|
|
|
+ input.value = "";
|
|
|
+ currentEditIndex.value = -1;
|
|
|
+ currentEditName.value = '';
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.service-info {
|
|
|
+ .main-content {
|
|
|
+ max-height: calc(100% - 40px);
|
|
|
+ overflow: auto;
|
|
|
+ padding: 15px 12px;
|
|
|
+ margin: 14px 12px;
|
|
|
+ border-radius: 12px;
|
|
|
+ background: #fff;
|
|
|
+ .service-title {
|
|
|
+ font-size: 18px;
|
|
|
+ color: #222222;
|
|
|
+ font-weight: 500;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ .label-icon {
|
|
|
+ width: 14px;
|
|
|
+ padding-right: 5px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .service-content {
|
|
|
+ margin-top: 12px;
|
|
|
+ padding-top: 12px;
|
|
|
+ border-top: 1px solid #F5F5F5;
|
|
|
+ .service-item {
|
|
|
+ .sub-title {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 500;
|
|
|
+ color: rgba(0, 0, 0, 0.9);
|
|
|
+ }
|
|
|
+ .tag-group {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 0 12px;
|
|
|
+ font-size: 16px;
|
|
|
+ .tag-item {
|
|
|
+ margin-top: 10px;
|
|
|
+ position: relative;
|
|
|
+ background: #E8F5FF;
|
|
|
+ border-radius: 8px;
|
|
|
+ color: #2199f8;
|
|
|
+ padding: 0 12px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ min-width: 26vw;
|
|
|
+ height: 48px;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 48px;
|
|
|
+ .text { display: inline-flex; align-items: center; }
|
|
|
+ .edit-icon { margin-left: 8px; }
|
|
|
+ .del-icon {
|
|
|
+ position: absolute;
|
|
|
+ right: -8px;
|
|
|
+ top: -8px;
|
|
|
+ background: #2199F8;
|
|
|
+ border-radius: 50%;
|
|
|
+ width: 16px; height: 16px;
|
|
|
+ font-size: 10px;
|
|
|
+ display: flex; align-items: center; justify-content: center;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ &.add-tag-group {
|
|
|
+ .tag-item {
|
|
|
+ color: #000000;
|
|
|
+ background: none;
|
|
|
+ border: 1px solid #999999;
|
|
|
+ &.self {
|
|
|
+ border: 1px solid #2199F8;
|
|
|
+ background: #E8F5FF;
|
|
|
+ color: #2199F8;
|
|
|
+ }
|
|
|
+ &.last-add {
|
|
|
+ background: #F7F7F7;
|
|
|
+ color: #343434;
|
|
|
+ border: none;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ .add-icon {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ margin-right: 3px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .service-item + .service-item {
|
|
|
+ margin-top: 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.add-tag-popup{
|
|
|
+ width: 90%;
|
|
|
+ padding: 20px 16px;
|
|
|
+ .popup-title{
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 500;
|
|
|
+ text-align: center;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ }
|
|
|
+ .ml-2 {
|
|
|
+ margin-left: 3px;
|
|
|
+ }
|
|
|
+ .popup-input{
|
|
|
+ margin-bottom: 30px;
|
|
|
+ }
|
|
|
+ .popup-button{
|
|
|
+ display: flex;
|
|
|
+ padding-top: 20px;
|
|
|
+ border-top: 1px solid rgba(0, 0, 0, 0.1);
|
|
|
+ div{
|
|
|
+ flex: 1;
|
|
|
+ font-size: 16px;
|
|
|
+ padding: 9px;
|
|
|
+ border-radius: 20px;
|
|
|
+ background: #2199F8;
|
|
|
+ color: #fff;
|
|
|
+ text-align: center;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ .cancel{
|
|
|
+ margin-right: 20px;
|
|
|
+ color: #000;
|
|
|
+ background: #fff;
|
|
|
+ border: 1px solid #999999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|