| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- <template>
- <div class="agricultural-dynamics">
- <!-- 任务列表 -->
- <div class="task-list">
- <div v-for="(task, index) in taskList" :key="index" class="task-item">
- <div class="task-content">
- <div class="task-header">
- <div class="task-status-tag">待完成</div>
- <div class="task-title">{{ task.title }}</div>
- </div>
- <div class="task-time">执行时间 {{ task.executionTime }}</div>
- </div>
- <div class="task-action" @click="handleTaskAction(task)" :class="{ orange: index === 1 }">
- {{ index === 0 ? "上传照片" : "确认执行时间" }}
- </div>
- </div>
- </div>
- <div class="title">农情互动</div>
- <!-- 内容区域 -->
- <div class="agricultural-list">
- <div v-if="!unansweredList.length" class="empty-block">暂无数据</div>
- <template v-else>
- <div class="agricultural-item" v-for="(item, index) in unansweredList" :key="index">
- <!-- 头部区域 -->
- <div class="header-section">
- <div class="header-left">
- <div class="farm-name">{{ item.farmName }}</div>
- <div class="tag-group">
- <div class="tag tag-blue">{{ item.typeName }}</div>
- <div class="tag tag-orange">托管客户</div>
- </div>
- </div>
- <div class="remind-btn" @click="handleRemind(item)">提醒客户</div>
- </div>
- <!-- 警告通知块 -->
- <div class="warning-block" v-if="item.latestPhenologyProgressBroadcast" v-html="item.latestPhenologyProgressBroadcast?.content"></div>
- <div class="timeline">
- <div class="timeline-item" v-for="timelineItem in item.timelineList" :key="timelineItem.id">
- <div class="timeline-left">
- <div class="dot"></div>
- <div class="line"></div>
- </div>
- <div class="timeline-right">
- <div class="date">
- 预计{{ timelineItem.daysUntilTrigger }}天后触发<span class="work-name">{{ timelineItem.farmWorkName }}</span>
- </div>
- <div class="text">
- 预计报价<span class="price">{{ timelineItem.estimatedCost }}元</span>
- <span class="action-detail" @click="showPriceSheetPopup(timelineItem)">查看报价单</span>
- </div>
- </div>
- <div class="timeline-action" @click="handleTimelineAction(timelineItem, item.farmId)">转入农事任务</div>
- </div>
- </div>
- </div>
- </template>
- </div>
- </div>
- <offer-popup ref="offerPopupRef"></offer-popup>
- <!-- 新增:激活上传弹窗 -->
- <active-upload-popup ref="activeUploadPopupRef" @handleUploadSuccess="handleUploadSuccess"></active-upload-popup>
-
- <!-- 服务报价单 -->
- <price-sheet-popup ref="priceSheetPopupRef"></price-sheet-popup>
- </template>
- <script setup>
- import router from "@/router";
- import { ref, onMounted } from "vue";
- import offerPopup from "@/components/popup/offerPopup.vue";
- import eventBus from "@/api/eventBus";
- import activeUploadPopup from "@/components/popup/activeUploadPopup.vue";
- import priceSheetPopup from "@/components/popup/priceSheetPopup.vue";
- // 任务列表数据
- const taskList = ref([
- { id: 1, title: "梢期杀虫", executionTime: "2025.05.06", status: "pending" },
- { id: 2, title: "梢期杀虫", executionTime: "2025.05.06", status: "pending" },
- ]);
- const offerPopupRef = ref(null);
- const handleTaskAction = (item) => {
- const data = {
- address: "岭南印象园东南",
- executeDate: "2025-11-19",
- executeEvidence: '["birdseye-look-mini/91754/1763544788985.jpg"]',
- farmArea: "50.089606952166854",
- farmId: 93684,
- farmMiniUserId: 91429,
- farmMiniUserName: "丝丝1",
- farmName: "17ss籼稻农场",
- farmWorkArrangeId: "124",
- farmWorkLibId: "2220005",
- farmWorkName: "蘖末防治",
- id: "276567",
- isFollow: null,
- isIgnored: 0,
- isPublic: 0,
- mapInfo: "11.19 蘖末防治",
- orderId: "778948195706212352",
- point: "POINT(113.407189 23.032344)",
- quoteCount: "1",
- solarTerm: null,
- typeId: "223",
- typeName: "丝苗米",
- };
- offerPopupRef.value.openPopup(data);
- };
- // 查询当前农资店的成员列表(只保留有“任务接单”权限的成员)
- const getManagerList = async () => {
- const { data } = await VE_API.mine.listManagerList({onlyExecutor: true});
- if (data && data.length > 0) {
- // 过滤 permissionList 中包含“任务接单”的成员
- executorList.value = data;
- }
- };
- const executorList = ref([])
- const handleTimelineAction = (item, farmId) => {
- // 处理转入农事任务逻辑
- eventBus.emit("activeUpload:show", {
- gardenIdVal: farmId,
- needExecutorVal: true,
- problemTitleVal: '请选择 ' + item.farmWorkName + ' 执行截止时间',
- imgDescVal: '请上传凭证(转入农事任务凭证)',
- arrangeIdVal: item.arrangeId,
- executorListVal: executorList.value,
- });
- };
- const priceSheetPopupRef = ref(null);
- const showPriceSheetPopup = (item) => {
- console.log('item', item)
- VE_API.z_farm_work_record.getDetail({ id: item.farmWorkId }).then(({ data }) => {
- const res = data[0];
- priceSheetPopupRef.value.handleShowPopup(res);
- });
- };
- const handleUploadSuccess = async () => {
- await getUnansweredFarms();
- };
- const handleRemind = (item) => {
- router.push(`/remind_customer?farmId=${item.farmId}`);
- };
- onMounted(() => {
- getUnansweredFarms();
- getManagerList()
- });
- //农情互动的农场列表接口(分页)
- const unansweredList = ref([]);
- const getUnansweredFarms = async () => {
- const params = {
- page: 0,
- limit: 3,
- };
- const res = await VE_API.home.listUnansweredFarms(params);
- unansweredList.value = (res.data || []).map(item => ({
- ...item,
- timelineList: []
- }));
-
- // 串行请求,一个完成后再请求下一个
- if(unansweredList.value.length){
- for(let i = 0; i < unansweredList.value.length; i++){
- await getFutureFarmWorkWarning(unansweredList.value[i]);
- }
- }
- };
- //查询未来农事预警
- const getFutureFarmWorkWarning = async (item) => {
- const res = await VE_API.home.listFutureFarmWorkWarning({farmId: item.farmId});
- item.timelineList = res.data || [];
- };
- </script>
- <style scoped lang="scss">
- .agricultural-dynamics {
- padding: 0 10px;
- // 任务列表样式
- .task-list {
- .task-item {
- display: flex;
- align-items: center;
- justify-content: space-between;
- background-color: #ffffff;
- border-radius: 8px;
- padding: 12px;
- margin-top: 10px;
- position: relative;
- overflow: hidden;
- &::after {
- content: "";
- position: absolute;
- top: -10px;
- right: 0;
- width: 72px;
- height: 72px;
- pointer-events: none;
- background: url("@/assets/img/home/task-icon.png") no-repeat center center / 100% 100%;
- }
- .task-content {
- .task-header {
- display: flex;
- align-items: center;
- margin-bottom: 4px;
- gap: 8px;
- }
- .task-status-tag {
- background-color: rgba(33, 153, 248, 0.1);
- color: #2199f8;
- font-size: 12px;
- padding: 1px 6px;
- border-radius: 2px;
- }
- .task-title {
- font-size: 16px;
- font-weight: 500;
- color: #1d2129;
- }
- .task-time {
- font-size: 12px;
- color: rgba(78, 89, 105, 0.5);
- }
- }
- .task-action {
- background-color: rgba(33, 153, 248, 0.1);
- color: #2199f8;
- border-radius: 25px;
- padding: 7px 14px;
- font-size: 12px;
- &.orange {
- color: #ff953d;
- background: rgba(255, 149, 61, 0.1);
- }
- }
- }
- }
- .title {
- font-size: 16px;
- font-weight: 500;
- color: #1d2129;
- margin-top: 10px;
- }
- .agricultural-list {
- .empty-block {
- display: flex;
- align-items: center;
- justify-content: center;
- height: 120px;
- color: #a0a0a0;
- font-size: 14px;
- background-color: #ffffff;
- border-radius: 8px;
- margin-top: 8px;
- }
- .agricultural-item {
- background-color: #ffffff;
- border-radius: 8px;
- padding: 8px 12px;
- margin-top: 8px;
- // 头部区域样式
- .header-section {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding-bottom: 5px;
- border-bottom: 0.5px solid rgba(0, 0, 0, 0.1);
- .header-left {
- display: flex;
- align-items: center;
- gap: 8px;
- .farm-name {
- font-size: 16px;
- font-weight: 500;
- color: #1d2129;
- }
- .tag-group {
- display: flex;
- gap: 4px;
- .tag {
- padding: 2px 8px;
- border-radius: 2px;
- font-size: 12px;
- &.tag-blue {
- background-color: #e8f3ff;
- color: #2199f8;
- }
- &.tag-orange {
- background-color: rgba(255, 149, 61, 0.1);
- color: #ff953d;
- }
- }
- }
- }
- .remind-btn {
- background-color: #2199f8;
- color: #ffffff;
- border-radius: 25px;
- padding: 7px 12px;
- font-size: 12px;
- }
- }
- // 警告通知块样式
- .warning-block {
- background-color: rgba(33, 153, 248, 0.1);
- border-radius: 5px;
- padding: 5px;
- margin-top: 8px;
- font-size: 12px;
- color: #252525;
- ::v-deep{
- p{
- padding: 0;
- margin: 0;
- }
- }
- }
- .timeline {
- margin-left: -5px;
- margin-top: 8px;
- .timeline-item {
- display: flex;
- align-items: flex-start;
- font-size: 14px;
- color: #ffffff;
- line-height: 22px;
- & + .timeline-item {
- margin-top: 10px;
- }
- .timeline-left {
- width: 22px;
- display: flex;
- flex-direction: column;
- align-items: center;
- .dot {
- width: 6px;
- height: 6px;
- border-radius: 50%;
- background: #a2d5fd;
- margin-top: 6px;
- }
- .line {
- border-left: 1px dashed #a2d5fd;
- margin-top: 4px;
- height: 28px;
- }
- }
- .timeline-right {
- padding-left: 5px;
- flex: 1;
- .date {
- color: #1d2129;
- font-weight: 500;
- font-size: 14px;
- line-height: 22px;
- }
- .text {
- font-size: 12px;
- color: #d7d7d7;
- .price {
- padding-left: 4px;
- }
- .action-detail {
- margin-left: 6px;
- color: #2199f8;
- border-bottom: 1px solid;
- }
- }
- .work-name {
- padding-left: 4px;
- }
- }
- .timeline-action {
- align-self: center;
- height: 28px;
- line-height: 28px;
- flex: none;
- background: rgba(33, 153, 248, 0.1);
- color: #2199f8;
- font-size: 12px;
- padding: 0px 11px;
- border-radius: 20px;
- }
- }
- }
- }
- }
- }
- </style>
|