| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- <template>
- <div class="service-manage">
- <custom-header name="服务维护"></custom-header>
- <ServiceInfo
- ref="serviceInfoRef"
- v-model:crops="crops"
- v-model:serviceTypes="serviceTypes"
- v-model:machines="machines"
- v-model:isEdit="isEdit"
- />
-
- <div class="page-action" v-if="isEdit">
- <div class="btn-item cancel" @click="isEdit = false">取消</div>
- <div class="btn-right">
- <div class="btn-item primary" @click="handleSave">保存服务类型</div>
- </div>
- </div>
- <div class="page-action" v-else>
- <div class="btn-item primary center-btn" @click="isEdit = true">编辑服务类型</div>
- </div>
- </div>
- </template>
- <script setup>
- import { ref, onMounted, onActivated, watch } from "vue";
- import customHeader from "@/components/customHeader.vue";
- import ServiceInfo from "@/components/pageComponents/ServiceInfo.vue";
- import { ElMessage } from "element-plus";
- const isEdit = ref(false);
- const serviceInfoRef = ref(null);
- // 默认数据
- const defaultCrops = [
- { name: "荔枝", isSelf: 0 },
- { name: "水稻", isSelf: 0 },
- { name: "菠萝", isSelf: 0 },
- { name: "柚子", isSelf: 0 },
- { name: "蔬菜", isSelf: 0 },
- { name: "小麦", isSelf: 0 },
- ];
- const defaultServiceTypes = [
- { name: "嫁接", isSelf: 0 },
- { name: "施肥打药", isSelf: 0 },
- { name: "修剪", isSelf: 0 },
- ];
- const defaultMachines = [
- { name: "植保机", isSelf: 0 },
- { name: "喷药车", isSelf: 0 },
- { name: "收割机", isSelf: 0 }
- ];
- // 三类数据:数组对象形式
- const crops = ref([]);
- const serviceTypes = ref([]);
- const machines = ref([]);
- // 将接口返回的字符串数组转换为对象数组(默认显示时使用)
- function convertApiDataToItems(apiList) {
- if (!Array.isArray(apiList)) {
- return [];
- }
- return apiList.map(item => {
- const name = typeof item === 'string' ? item : (item.name || item);
- // 检查是否是默认数据中的项
- const isDefault = defaultCrops.some(d => d.name === name) ||
- defaultServiceTypes.some(d => d.name === name) ||
- defaultMachines.some(d => d.name === name);
- return {
- name: name,
- isSelf: isDefault ? 0 : 1, // 如果是默认数据中的,isSelf=0,否则是用户自定义的
- selected: true // 接口返回的都是已保存的,所以都选中
- };
- });
- }
- // 合并数据:编辑时将默认数据与接口数据合并,name相同的设置为选中
- function mergeDataForEdit(defaultList, apiList) {
- // 创建 API 返回数据的名称集合(用于判断是否选中)
- const apiNameSet = new Set(apiList.map(item => typeof item === 'string' ? item : (item.name || item)));
-
- // 合并逻辑:默认数据 + API 数据(去重)
- const merged = [...defaultList];
-
- // 标记默认数据中哪些被选中(name 在 API 数据中存在)
- merged.forEach(item => {
- if (apiNameSet.has(item.name)) {
- item.selected = true;
- } else {
- item.selected = false;
- }
- });
-
- // 添加 API 中存在但默认数据中不存在的项(这些是用户自定义的)
- apiList.forEach(apiItem => {
- const apiName = typeof apiItem === 'string' ? apiItem : (apiItem.name || apiItem);
- const exists = merged.some(item => item.name === apiName);
- if (!exists) {
- merged.push({
- name: apiName,
- isSelf: 1, // 标记为用户自定义
- selected: true
- });
- }
- });
-
- return merged;
- }
- // 获取服务详情
- function getServiceDetail() {
- VE_API.z_agricultural_store.getServiceDetail().then(({ data }) => {
- if (data) {
- // 默认情况下,只显示接口返回的数据
- crops.value = convertApiDataToItems(data.serviceCropsJson || []);
- serviceTypes.value = convertApiDataToItems(data.serviceTypeJson || []);
- machines.value = convertApiDataToItems(data.agriculturalEquipmentJson || []);
- } else {
- // 如果没有数据,显示空数组
- crops.value = [];
- serviceTypes.value = [];
- machines.value = [];
- }
- }).catch(() => {
- // 获取失败,显示空数组
- crops.value = [];
- serviceTypes.value = [];
- machines.value = [];
- });
- }
- // 监听编辑状态,编辑时合并默认数据
- watch(isEdit, (newVal) => {
- if (newVal) {
- // 进入编辑模式,合并默认数据
- VE_API.z_agricultural_store.getServiceDetail().then(({ data }) => {
- if (data) {
- crops.value = mergeDataForEdit(defaultCrops, data.serviceCropsJson || []);
- serviceTypes.value = mergeDataForEdit(defaultServiceTypes, data.serviceTypeJson || []);
- machines.value = mergeDataForEdit(defaultMachines, data.agriculturalEquipmentJson || []);
- } else {
- // 如果没有数据,使用默认数据(都不选中)
- crops.value = defaultCrops.map(item => ({ ...item, selected: false }));
- serviceTypes.value = defaultServiceTypes.map(item => ({ ...item, selected: false }));
- machines.value = defaultMachines.map(item => ({ ...item, selected: false }));
- }
- }).catch(() => {
- // 获取失败,使用默认数据(都不选中)
- crops.value = defaultCrops.map(item => ({ ...item, selected: false }));
- serviceTypes.value = defaultServiceTypes.map(item => ({ ...item, selected: false }));
- machines.value = defaultMachines.map(item => ({ ...item, selected: false }));
- });
- } else {
- // 退出编辑模式,重新获取数据(只显示接口返回的数据)
- getServiceDetail();
- }
- });
- // 保存服务类型
- function handleSave() {
- if (!serviceInfoRef.value) {
- return;
- }
-
- const serviceInfo = serviceInfoRef.value.getServiceInfo();
-
- VE_API.z_agricultural_store.updateService({
- serviceCropsJson: serviceInfo.serviceCropsJson,
- serviceTypeJson: serviceInfo.serviceTypeJson,
- agriculturalEquipmentJson: serviceInfo.agriculturalEquipmentJson
- }).then(({ code, msg }) => {
- if (code === 0) {
- ElMessage.success("保存成功");
- isEdit.value = false;
- // 重新获取数据
- getServiceDetail();
- } else {
- ElMessage.error(msg || "保存失败");
- }
- }).catch(() => {
- ElMessage.error("保存失败,请重试");
- });
- }
- onMounted(() => {
- getServiceDetail();
- });
- onActivated(() => {
- getServiceDetail();
- });
- </script>
- <style lang="scss" scoped>
- .service-manage {
- width: 100%;
- height: 100vh;
- background: #F5F7FB;
-
- .page-action {
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- padding: 12px 12px;
- background: #fff;
- box-shadow: 2px 2px 4.5px rgba(0, 0, 0, 0.4);
- display: flex;
- justify-content: space-between;
- align-items: center;
- .btn-item {
- height: 40px;
- line-height: 41px;
- border-radius: 20px;
- width: fit-content;
- padding: 0 20px;
- color: #666666;
- font-size: 14px;
- &.del {
- color: #ff943d;
- background: rgba(255, 148, 61, 0.1);
- }
- &.cancel {
- border: 1px solid rgba(153, 153, 153, 0.5);
- }
- &.primary {
- color: #fff;
- background: linear-gradient(#76c3ff, #2199f8);
- }
- }
- .center-btn {
- margin: 0 auto;
- }
- .btn-right {
- display: flex;
- gap: 10px;
- }
- }
- }
- </style>
|