| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961 |
- <template>
- <div class="task-page" :style="{ height: `calc(100vh - ${tabBarHeight}px)` }">
- <div class="task-top">
- <div class="map-container" ref="mapContainer"></div>
- </div>
- <div class="calendar-container">
- <customCalendar ref="calendarRef" @dateSelect="handleDateSelect"></customCalendar>
- </div>
- <div class="task-list">
- <div class="list-filter">
- <div class="filter-item" :class="{ active: activeIndex === 0 }" @click="handleActiveFilter(0)">
- {{ t("workExecute.pending") }}({{ taskCounts[0] || 0 }})
- </div>
- <div class="filter-item" :class="{ active: activeIndex === 2 }" @click="handleActiveFilter(2)">
- {{ t("workExecute.accepted") }}({{ taskCounts[2] || 0 }})
- </div>
- <div class="filter-item" :class="{ active: activeIndex === 3 }" @click="handleActiveFilter(3)">
- {{ t("workExecute.executing") }}({{ taskCounts[3] || 0 }})
- </div>
- <div class="filter-item" :class="{ active: activeIndex === 4 }" @click="handleActiveFilter(3)">
- {{ t("workExecute.completed") }}({{ taskCounts[4] || 0 }})
- </div>
- </div>
- <div class="list-box">
- <div class="list-header">
- <div class="select-group">
- <el-select class="select-item" v-model="selectParma.farmWorkTypeId" :placeholder="t('workExecute.farmWorkType')"
- @change="getSimpleList">
- <el-option v-for="item in farmWorkTypeList" :key="item.id"
- :label="item.id === 0 ? t('workExecute.all') : item.name"
- :value="item.id" />
- </el-select>
- <el-select class="select-item" v-model="selectParma.districtCode" :placeholder="t('workExecute.farmFilter')"
- @change="getSimpleList">
- <el-option v-for="item in districtList" :key="item.code" :label="item.name"
- :value="item.code" />
- </el-select>
- </div>
- <!-- <div class="action-btn">{{ t("workExecute.batchAccept") }}</div> -->
- </div>
- <!-- 任务列表 -->
- <div class="work-task-list" v-loading="loading" element-loading-background="rgba(0, 0, 0, 0.3)">
- <div class="task-item" v-for="(item, index) in taskList" :key="index"
- :class="isTimeoutItem(index) ? 'timeout-item' : ''" @click="handleItem(item, index)">
- <div class="item-title">
- <img class="task-icon" src="@/assets/img/home/task.png" alt="">
- <span class="title-text">{{ item.operation?.name }}</span>
- <span class="task-status" :class="`task-status--${item.operation?.type}`">{{
- item.operation?.typeName }}</span>
- </div>
- <span class="task-tag timeout" v-if="isTimeoutItem(index)">
- <el-icon>
- <WarningFilled />
- </el-icon>
- {{ getTimeoutText() }}
- </span>
- <span class="task-tag" v-else>
- {{ getStatusLabel(activeStatus) }}
- </span>
- <div class="item-content">
- <div class="item-info">
- <div class="info-item">
- <div class="info-name">{{ t("workExecute.responsible") }}</div><span class="val-text">
- 某某某、某某某</span>
- </div>
- <div class="info-item" v-if="mode !== 'review'">
- <div class="info-name">{{ t("workExecute.farmWorkDetail") }}</div><span class="val-text">
- {{ item.operation?.drug }}</span>
- </div>
- <div class="info-item">
- <div class="info-name">{{ t("workExecute.farmSituation") }}</div><span class="val-text">
- {{ item.operation?.work_reason }}</span>
- </div>
- </div>
- <div class="excutor-info">
- <div class="executor-stats">
- <div class="stat-cell">
- <div class="stat-value">
- {{ item.time ? formatGMTToYMD(item.time) : "--" }}
- </div>
- <div class="stat-label">{{ t("workExecute.executeTime") }}</div>
- </div>
- <div class="cell-line"></div>
- <div class="stat-cell">
- <div class="stat-value">{{ item.geohash_sample || "--" }}</div>
- <div class="stat-label">{{ t("workExecute.executeArea") }}</div>
- </div>
- <div class="cell-line"></div>
- <div class="stat-cell">
- <div class="stat-value">{{ item.operation?.machine_code || "--" }}</div>
- <div class="stat-label">{{ t("workExecute.executeMachine") }}</div>
- </div>
- </div>
- </div>
- </div>
- <div class="unqualified-reason" v-if="activeStatus === '未达标'">
- {{ t("workExecute.unqualifiedReason") }}{{ item.operation?.reason || t("workExecute.defaultUnqualifiedReason") }}
- </div>
- <div class="compare-imgs" v-if="activeStatus === '未达标' && (item.beforeImage || item.afterImage)"
- @click.stop>
- <div class="img-tag">{{ t("workExecute.before") }}</div>
- <div class="img-tag right-tag">{{ t("workExecute.after") }}</div>
- <div class="img-item" v-if="item.beforeImage">
- <img :src="getWorkImageUrl(item.beforeImage)" alt="" />
- </div>
- <div class="img-item" v-if="item.afterImage">
- <img :src="getWorkImageUrl(item.afterImage)" alt="" />
- </div>
- </div>
- <div class="task-footer">
- <div class="farm-info">{{ t("workExecute.fromFarm") }}</div>
- <div class="btn-group" v-if="getItemStatusButtons(index).length">
- <div v-for="btn in getItemStatusButtons(index)" :key="btn.label" class="edit-btn"
- :class="btn.type" @click.stop="handleStatusBtn(btn, item, index)">
- {{ btn.label }}
- </div>
- </div>
- </div>
- </div>
- <div class="empty-tip" v-if="!loading && taskList.length === 0">{{ t("workExecute.noData") }}</div>
- </div>
- </div>
- </div>
- </div>
- <!-- <upload-execute ref="uploadExecuteRef" :onlyShare="onlyShare" @uploadSuccess="handleUploadSuccess" /> -->
- <!-- 服务报价单 -->
- <!-- <price-sheet-popup :key="activeIndex" ref="priceSheetPopupRef"></price-sheet-popup> -->
- <!-- 新增:激活上传弹窗 -->
- <!-- <active-upload-popup ref="activeUploadPopupRef" @handleUploadSuccess="handleUploadSuccess"></active-upload-popup> -->
- </template>
- <script setup>
- import { computed, nextTick, onActivated, onMounted, ref, watch } from "vue";
- import { useRoute } from "vue-router";
- import { useStore } from "vuex";
- import IndexMap from "./index";
- import { useRouter } from "vue-router";
- import { WarningFilled } from "@element-plus/icons-vue";
- import { ElMessage } from "element-plus";
- import config from "@/api/config.js";
- import customCalendar from "./components/calendar.vue";
- import { useI18n } from "@/i18n";
- const { t } = useI18n();
- const store = useStore();
- const router = useRouter();
- const route = useRoute();
- const indexMap = new IndexMap();
- const mapContainer = ref(null);
- const tabBarHeight = computed(() => store.state.home.tabBarHeight);
- const selectParma = ref({
- farmWorkTypeId: null,
- districtCode: null,
- });
- // 任务列表数据(用于显示,可能被筛选)
- const taskList = ref([
- {
- time: "Fri, 22 May 2026 00:00:00 GMT",
- geohash_sample: "ws0gs49ns213",
- farmName: "冬季清园",
- typeName: "荔枝",
- userType: 1,
- address: "广东省广州市从化区太平镇凤凰路88号",
- farmPoint: "POINT(113.61652616170711 23.58399613872042)",
- sourceData: {
- currentPhenologyName: "花芽分化",
- currentPhenologyStartDate: "2026-01-15",
- daysUntilNext: 3,
- },
- operation: {
- name: "冬季清园",
- type: "1",
- typeName: "标准类",
- work_reason: "近期气温回升,需及时清理园内枯枝落叶,减少病虫越冬基数",
- drug: "石硫合剂 500倍液",
- machine_code: "DJI-T40-001",
- work_id: 5001,
- },
- },
- {
- time: "Mon, 26 May 2026 00:00:00 GMT",
- geohash_sample: "ws0gefxm68u5",
- farmName: "施肥促花",
- typeName: "柑橘",
- userType: 2,
- address: "广东省肇庆市德庆县官圩镇果园示范区",
- farmPoint: "POINT(113.62757101477101 23.590796948574365)",
- sourceData: {
- currentPhenologyName: "开花期",
- currentPhenologyStartDate: "2026-02-20",
- daysUntilNext: 12,
- },
- operation: {
- name: "施肥促花",
- type: "2",
- typeName: "感知类",
- work_reason: "花芽分化期养分需求增加,需补充磷钾肥",
- drug: "磷酸二氢钾 0.3%",
- machine_code: "DJI-T50-003",
- work_id: 5002,
- },
- },
- {
- time: "Wed, 28 May 2026 00:00:00 GMT",
- geohash_sample: "ws0gefzjqqqw",
- farmId: 1003,
- farmName: "病虫害防治",
- typeName: "水稻",
- userType: 1,
- address: "广东省清远市清城区龙塘镇农业科技园",
- farmPoint: "POINT(113.62240816252164 23.59499176519138)",
- sourceData: {
- currentPhenologyName: "分蘖期",
- currentPhenologyStartDate: "2026-03-01",
- daysUntilNext: 8,
- },
- operation: {
- name: "病虫害防治",
- type: "1",
- typeName: "复核类",
- work_reason: "监测到蚜虫活动增多,建议及时喷药防治",
- drug: "吡虫啉 1500倍液",
- machine_code: "DJI-T40-002",
- work_id: 5003,
- },
- },
- ]);
- const mode = "execute";
- const activeStatus = ref("待接受");
- const STATUS_BTN_MAP = {
- 待接受: [
- { labelKey: "workExecute.redispatch", type: "normal", action: "redispatch" },
- { labelKey: "workExecute.remindAccept", type: "primary", action: "remindAccept" },
- ],
- 已接受: [{ labelKey: "workExecute.remindExecute", type: "primary", action: "remindExecute" }],
- 执行中: [{ labelKey: "workExecute.remindComplete", type: "primary", action: "remindComplete" }],
- 已超时: [
- { labelKey: "workExecute.redispatch", type: "normal", action: "redispatch" },
- { labelKey: "workExecute.remindAccept", type: "primary", action: "remindAccept" },
- ],
- 未达标: [{ labelKey: "workExecute.redispatchAgain", type: "primary", action: "redispatch" }],
- };
- const STATUS_LABEL_MAP = {
- 待接受: "workExecute.pending",
- 已接受: "workExecute.accepted",
- 执行中: "workExecute.executing",
- 已完成: "workExecute.completed",
- 已超时: "workExecute.timeout",
- 未达标: "workExecute.unqualified",
- };
- const getStatusLabel = (status) => t(STATUS_LABEL_MAP[status] || status);
- const isTimeoutItem = (index) => index === 0;
- const getTimeoutRemindBtn = () => {
- const map = {
- 待接受: { labelKey: "workExecute.remindAccept", type: "primary", action: "remindAccept" },
- 已接受: { labelKey: "workExecute.remindExecute", type: "primary", action: "remindExecute" },
- 执行中: { labelKey: "workExecute.remindComplete", type: "primary", action: "remindComplete" },
- };
- const btn = map[activeStatus.value];
- return btn ? { ...btn, label: t(btn.labelKey) } : null;
- };
- const mapStatusButtons = (buttons) =>
- buttons.map((btn) => ({
- ...btn,
- label: t(btn.labelKey),
- }));
- const getItemStatusButtons = (index) => {
- const baseButtons = mapStatusButtons(STATUS_BTN_MAP[activeStatus.value] || []);
- if (!isTimeoutItem(index)) {
- return baseButtons;
- }
- if (activeStatus.value === "待接受") {
- return baseButtons;
- }
- const remindBtn = getTimeoutRemindBtn();
- if (remindBtn) {
- return [
- { label: t("workExecute.redispatch"), type: "normal", action: "redispatch" },
- remindBtn,
- ];
- }
- return [
- { label: t("workExecute.redispatch"), type: "normal", action: "redispatch" },
- ...baseButtons,
- ];
- };
- const getTimeoutText = () => {
- const map = {
- 待接受: "workExecute.acceptTimeout",
- 已接受: "workExecute.executeTimeout",
- 执行中: "workExecute.completeTimeout",
- };
- return t(map[activeStatus.value] || "workExecute.timeout");
- };
- const formatGMTToYMD = (gmtString) => {
- const date = new Date(gmtString);
- return date.toISOString().split("T")[0];
- };
- const getWorkImageUrl = (image) => {
- if (!image?.cloud_filename) return "";
- return config.base_img_url3 + image.cloud_filename;
- };
- const handleItem = (item, index) => {
- router.push({
- path: "/agri_record_detail",
- query: {
- miniJson: JSON.stringify({
- id: item.operation?.work_id,
- status: activeStatus.value,
- }),
- },
- });
- };
- const handleStatusBtn = (btn, item, index) => {
- if (btn.action === "redispatch") {
- ElMessage.info(t("workExecute.redispatchMsg", { name: item.operation?.name }));
- } else {
- ElMessage.success(t("workExecute.remindSuccess"));
- }
- };
- const calendarRef = ref(null);
- const filterDate = ref(null);
- const fullTaskList = ref([]);
- const getCalendarTaskList = (list) => {
- return list.map((item) => ({
- expectedExecuteDate: item.time,
- executeDeadlineDate: item.time,
- }));
- };
- const syncCalendarData = () => {
- nextTick(() => {
- calendarRef.value?.setSolarTerm(getCalendarTaskList(fullTaskList.value));
- });
- };
- const handleDateSelect = (date) => {
- filterDate.value = date;
- // if (!date) {
- // taskList.value = [...fullTaskList.value];
- // } else {
- // taskList.value = fullTaskList.value.filter((item) => {
- // if (!item.time) return false;
- // return formatGMTToYMD(item.time) === date;
- // });
- // }
- syncCalendarData();
- };
- // 各状态任务数量
- const taskCounts = ref([0, 0, 0]);
- // 当前选中的筛选索引
- const activeIndex = ref(2);
- const noData = ref(false);
- const loading = ref(false);
- // 分页相关
- const page = ref(0);
- const limit = ref(10);
- const loadingMore = ref(false);
- const finished = ref(false);
- // 查询未来农事预警
- const getFutureFarmWorkWarning = async (item) => {
- const res = await VE_API.home.listFutureFarmWorkWarning({ farmId: item.farmId });
- item.timelineList = res.data || [];
- };
- const cityCode = ref("");
- //根据城市的坐标返回区县列表
- const districtList = ref([]);
- //农事类型列表
- const farmWorkTypeList = ref([]);
- function getFarmWorkTypeList() {
- VE_API.z_farm_work_record.getFarmWorkTypeList().then(({ data }) => {
- farmWorkTypeList.value = data;
- farmWorkTypeList.value.unshift({ id: 0, name: "全部" });
- });
- }
- const mapPoint = ref(null);
- onMounted(() => {
- mapPoint.value = store.state.home.miniUserLocationPoint;
- fullTaskList.value = [...taskList.value];
- // getDistrictListByCity();
- resetAndLoad();
- getFarmWorkTypeList();
- syncCalendarData();
- nextTick(() => {
- indexMap.initMap(mapPoint.value, mapContainer.value, true);
-
- // 更新地图数据
- indexMap.initData(taskList.value, '', 'farmPoint');
- });
- });
- onActivated(() => {
- if (route.query.noReload) {
- return;
- }
- // 确保地图已初始化,使用 nextTick 等待 DOM 更新
- nextTick(() => {
- // 检查地图实例是否已初始化
- if (!indexMap.kmap) {
- // 如果地图未初始化,重新初始化
- if (mapContainer.value) {
- mapPoint.value = store.state.home.miniUserLocationPoint;
- indexMap.initMap(mapPoint.value, mapContainer.value, true);
- // 等待地图初始化完成后再加载数据
- setTimeout(() => {
- resetAndLoad();
- }, 300);
- return;
- }
- } else {
- // 如果地图已初始化,需要等待 tab 切换完成,容器完全可见后再更新尺寸
- // Tab 切换时容器可能被隐藏,需要更长的延迟确保容器可见
- if (mapContainer.value && indexMap.kmap.map) {
- // 检查容器是否可见
- const checkAndUpdateSize = () => {
- const container = mapContainer.value;
- if (container) {
- const rect = container.getBoundingClientRect();
- // 如果容器可见(有宽度和高度),更新地图尺寸
- if (rect.width > 0 && rect.height > 0) {
- indexMap.kmap.map.updateSize();
- } else {
- // 如果容器不可见,继续等待
- setTimeout(checkAndUpdateSize, 100);
- }
- }
- };
- // 延迟检查,确保 tab 切换完成
- setTimeout(checkAndUpdateSize, 200);
- }
- }
- resetAndLoad();
- });
- });
- // 监听 activeIndex 变化,重新加载数据
- watch(activeIndex, () => {
- resetAndLoad();
- });
- // 加载列表数据(支持分页)
- async function getSimpleList(isLoadMore = false) {
- if (!isLoadMore) {
- // 重置分页
- page.value = 0;
- finished.value = false;
- // taskList.value = [];
- loading.value = true;
- } else {
- loadingMore.value = true;
- }
- const params = {
- ...selectParma.value,
- page: page.value,
- limit: limit.value,
- flowStatus: 5,
- };
- try {
- const { data } = await VE_API.home.listUnansweredFarms(params);
- if (data && data.length > 0) {
- // 为每个item初始化timelineList
- const newItems = data.map((item) => {
- let sourceData = item?.latestPhenologyProgressBroadcast?.sourceData;
- if (sourceData) {
- try {
- sourceData = JSON.parse(sourceData);
- } catch (e) {
- console.error("解析sourceData失败:", e);
- sourceData = null;
- }
- }
- return {
- ...item,
- sourceData,
- timelineList: [],
- };
- });
- // 串行请求,为每个农场获取时间轴数据
- for (let i = 0; i < newItems.length; i++) {
- await getFutureFarmWorkWarning(newItems[i]);
- }
- // 追加数据
- // const newTaskList = [...taskList.value, ...newItems];
- // taskList.value = newTaskList.filter(item => item.timelineList.length > 0);
- // 更新分页
- page.value += 1;
- // 判断是否还有更多数据
- if (data.length < limit.value) {
- finished.value = true;
- }
- // 更新地图数据
- indexMap.initData(taskList.value, '', 'farmPoint');
- } else {
- finished.value = true;
- if (taskList.value.length === 0) {
- noData.value = true;
- }
- }
- // 数据处理完成后再设置loading为false
- if (!isLoadMore) {
- loading.value = false;
- } else {
- loadingMore.value = false;
- }
- } catch (error) {
- console.error("获取任务列表失败:", error);
- if (!isLoadMore) {
- loading.value = false;
- } else {
- loadingMore.value = false;
- }
- finished.value = true;
- if (taskList.value.length === 0) {
- noData.value = true;
- }
- }
- }
- // 滚动加载更多
- const onLoad = () => {
- if (!finished.value && !loadingMore.value) {
- getSimpleList(true);
- }
- };
- // 重置并重新加载
- const resetAndLoad = () => {
- getSimpleList(false);
- };
- function handleActiveFilter(i) {
- activeIndex.value = i;
- selectParma.value.districtCode = cityCode.value;
- selectParma.value.farmWorkTypeId = null;
- const statusMap = { 0: "待接受", 2: "已接受", 3: "执行中" };
- activeStatus.value = statusMap[i] || "待接受";
- filterDate.value = null;
- taskList.value = [...fullTaskList.value];
- calendarRef.value?.clearSelection();
- syncCalendarData();
- }
- function handleRemindCustomer(item) {
- // 接受
- }
- </script>
- <style lang="scss" scoped>
- .task-page {
- width: 100%;
- height: calc(100vh - 50px);
- overflow: auto;
- box-sizing: border-box;
- background: #FFFFFF;
- .map-container {
- width: 100%;
- height: 162px;
- clip-path: inset(0px round 8px);
- }
- .list-box {
- background: #F1F3F4;
- padding: 12px 12px 8px 12px;
- .list-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- .action-btn {
- box-sizing: border-box;
- height: 32px;
- line-height: 30px;
- color: #2199F8;
- font-size: 14px;
- border-radius: 5px;
- padding: 0 10px;
- background: #FFFFFF;
- border: 1px solid #2199F8;
- color: #2199F8;
- }
- }
- }
- .select-group {
- display: flex;
- padding: 0px 12px 0 12px;
- .select-item {
- width: 100%;
- ::v-deep {
- .el-select__wrapper {
- text-align: center;
- gap: 2px;
- box-shadow: none;
- justify-content: center;
- background: none;
- }
- .el-select__selection {
- flex: none;
- width: fit-content;
- }
- .el-select__placeholder {
- position: static;
- transform: none;
- width: fit-content;
- color: rgba(0, 0, 0, 0.2);
- }
- .el-select__caret {
- color: rgba(0, 0, 0, 0.2);
- }
- }
- }
- }
- .calendar-container {
- padding: 4px 12px 8px 12px;
- }
- .task-top {
- padding: 10px 12px 0 12px;
- }
- .task-content-loading {
- height: 80px;
- border-radius: 8px;
- position: absolute;
- top: 60px;
- left: 0;
- width: 100%;
- }
- .task-content {
- min-height: 80px;
- }
- .empty-data {
- text-align: center;
- font-size: 14px;
- color: #6f7274;
- padding: 20px 0;
- }
- .task-list {
- position: relative;
- background: #fff;
- }
- .list-filter {
- display: flex;
- align-items: center;
- justify-content: space-around;
- margin-top: 10px;
- .filter-item {
- padding: 0 6px;
- height: 32px;
- color: #1D2129;
- font-size: 14px;
- border-radius: 20px;
- position: relative;
- &.active {
- color: #2199f8;
- &::after {
- content: "";
- position: absolute;
- bottom: 0;
- left: 0;
- width: 100%;
- height: 2px;
- background: #2199f8;
- }
- }
- }
- }
- .work-task-list {
- margin-top: 10px;
- .task-item {
- margin-top: 10px;
- background: #fff;
- border-radius: 8px;
- padding: 12px 16px;
- border: 1px solid rgba(0, 0, 0, 0.08);
- position: relative;
- &.timeout-item {
- border: 1px solid #f74e4e;
- }
- .item-title {
- display: flex;
- align-items: center;
- padding-bottom: 10px;
- border-bottom: 1px solid rgba(0, 0, 0, 0.06);
- color: #1d2129;
- font-size: 16px;
- .task-icon {
- width: 16px;
- }
- .title-text {
- padding-left: 8px;
- }
- .task-status {
- margin-left: 8px;
- border-radius: 2px;
- height: 20px;
- line-height: 20px;
- padding: 1px 6px;
- box-sizing: border-box;
- font-size: 12px;
- color: #ffb32f;
- background: rgba(255, 179, 47, 0.1);
- &.task-status--1 {
- background: rgba(33, 153, 248, 0.1);
- color: #2199f8;
- }
- &.task-status--2 {
- background: rgba(255, 179, 47, 0.1);
- color: #FFB32F;
- }
- &.task-status--3 {
- background: rgba(58, 173, 148, 0.1);
- color: #3AAD94;
- }
- }
- }
- .task-tag {
- position: absolute;
- right: 0;
- top: 0;
- background: rgba(255, 149, 61, 0.1);
- color: #F46E00;
- font-size: 12px;
- padding: 0 10px;
- height: 25px;
- line-height: 25px;
- border-radius: 0 8px 0 8px;
- &.timeout {
- background: rgba(255, 106, 106, 0.1);
- color: #FF6A6A;
- display: flex;
- align-items: center;
- gap: 2px;
- }
- }
- .item-content {
- padding: 12px 0;
- .excutor-info {
- margin-top: 12px;
- background: rgba(189, 189, 189, 0.1);
- border-radius: 6px;
- padding-bottom: 12px;
- .excutor-info-top {
- padding: 12px 12px 0 12px;
- }
- }
- .executor-stats {
- display: flex;
- align-items: center;
- padding-top: 10px;
- justify-content: space-around;
- }
- .cell-line {
- height: 20px;
- width: 1px;
- background: #e5e6eb;
- }
- .stat-value {
- font-size: 14px;
- font-weight: 500;
- color: #0B0B0B;
- margin-bottom: 4px;
- word-break: break-all;
- }
- .stat-label {
- font-size: 12px;
- line-height: 20px;
- color: rgba(107, 107, 107, 0.5);
- text-align: center;
- }
- }
- .item-info {
- color: rgba(111, 114, 116, 0.6);
- font-size: 14px;
- line-height: 21px;
- .info-item {
- display: flex;
- .info-name {
- flex: none;
- }
- }
- .val-text {
- // color: #1d2129;
- }
- .info-item+.info-item {
- padding-top: 6px;
- }
- }
- .task-footer {
- padding-top: 4px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- .farm-info {
- font-size: 14px;
- color: rgba(32, 32, 32, 0.4);
- }
- }
- .btn-group {
- display: flex;
- align-items: center;
- justify-content: end;
- gap: 10px;
- }
- .edit-btn {
- height: 30px;
- padding: 0 16px;
- border-radius: 24px;
- text-align: center;
- line-height: 30px;
- font-size: 14px;
- &.normal {
- background: #F6F6F6;
- color: #000000;
- }
- &.primary {
- background: #FF953D;
- color: #fff;
- }
- }
- .compare-imgs {
- display: flex;
- align-items: center;
- gap: 10px;
- position: relative;
- margin: 10px 0;
- .img-tag {
- position: absolute;
- z-index: 10;
- top: 0;
- left: 0;
- font-size: 12px;
- color: #fff;
- background: rgba(0, 0, 0, 0.7);
- border-radius: 5px 0 5px 0;
- padding: 0 8px;
- height: 15px;
- line-height: 15px;
- &.right-tag {
- right: 0;
- left: auto;
- border-radius: 0 5px 0 5px;
- }
- }
- .img-item {
- flex: 1;
- height: 120px;
- overflow: hidden;
- border: 0.5px solid rgba(0, 0, 0, 0.1);
- border-radius: 5px;
- img {
- width: 100%;
- height: 100%;
- border-radius: 5px;
- object-fit: cover;
- }
- }
- }
- }
- .unqualified-reason {
- color: #f74e4e;
- font-size: 12px;
- padding: 4px 10px;
- background: rgba(247, 78, 78, 0.08);
- border-radius: 4px;
- line-height: 18px;
- }
- .empty-tip {
- text-align: center;
- color: #86909c;
- font-size: 14px;
- padding: 20px 0;
- }
- }
- }
- </style>
|