ソースを参照

Merge branch 'supplies' of http://www.sysuimars.cn:3000/feiniao/feiniao-farm-h5 into supplies

wangsisi 3 日 前
コミット
85a60449f4

+ 14 - 0
src/router/globalRoutes.js

@@ -447,4 +447,18 @@ export default [
         meta: { keepAlive: true },
         component: () => import("@/views/old_mini/interactionList/confirmArea.vue"),
     },
+    // 天气详情
+    {
+        path: "/weather_detail",
+        name: "WeatherDetail",
+        meta: { keepAlive: true },
+        component: () => import("@/views/old_mini/weather_detail/index.vue"),
+    },
+    // 农事详情
+    {
+        path: "/work_detail",
+        name: "WorkDetail",
+        meta: { keepAlive: true },
+        component: () => import("@/views/old_mini/work_detail/index.vue"),
+    },
 ];

+ 384 - 0
src/views/old_mini/weather_detail/index.vue

@@ -0,0 +1,384 @@
+<template>
+  <div class="weather-detail">
+    <custom-header name="气象详情"></custom-header>
+
+    <div class="weather-detail-content">
+    <!-- 顶部农场信息 -->
+    <div class="farm-card">
+        <div class="farm-right">
+            <img class="farm-point" src="@/assets/img/home/farm-point.png" alt="">
+        </div>
+      <div class="farm-left">
+        <div class="farm-name-row">
+          <span class="farm-name">{{ farmInfo.name }}</span>
+          <span class="farm-tag">桂味</span>
+        </div>
+        <div class="farm-address">
+          {{ farmInfo.address }}
+        </div>
+      </div>
+    </div>
+
+    <div class="weather-chart-container">
+        <div class="weather-chart-wrapper">
+            <div 
+                class="weather-chart-slider" 
+                :style="{ transform: `translateX(-${currentChartIndex * 50}%)` }"
+            >
+                <div class="weather-chart-item">
+                    <weather-chart :key="1" class="weather-chart" :weather-data="pastWeatherData"></weather-chart>
+                </div>
+                <div class="weather-chart-item">
+                    <weather-chart :key="2" class="weather-chart" :weather-data="weatherData"></weather-chart>
+                </div>
+            </div>
+        </div>
+        
+        <!-- 左箭头 -->
+        <div 
+            v-if="currentChartIndex > 0" 
+            class="weather-arrow weather-arrow-left"
+            @click="prevChart"
+        >
+            <el-icon><ArrowLeftBold /></el-icon>
+        </div>
+        
+        <!-- 右箭头 -->
+        <div 
+            v-if="currentChartIndex < 1" 
+            class="weather-arrow weather-arrow-right"
+            @click="nextChart"
+        >
+            <el-icon><ArrowRightBold /></el-icon>
+        </div>
+    </div>
+
+    <!-- 指标 Tab -->
+    <div class="tab-row">
+      <div
+        v-for="tab in tabs"
+        :key="tab.key"
+        class="tab-item"
+        :class="{ active: currentTab === tab.key }"
+        @click="currentTab = tab.key"
+      >
+        {{ tab.label }}
+      </div>
+    </div>
+
+    <!-- 风险列表 -->
+    <div class="risk-list">
+      <div
+        v-for="(item, index) in currentRiskList"
+        :key="index"
+        class="risk-item"
+      >
+        <div class="risk-title-row">
+          <span class="risk-title">{{ item.title }}</span>
+          <span class="risk-level">{{ item.level }}</span>
+        </div>
+        <div class="risk-desc">
+          {{ item.desc }}
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { computed, ref, onMounted } from "vue";
+import customHeader from "@/components/customHeader.vue";
+import weatherChart from "@/components/weatherChart.vue";
+import { useStore } from "vuex";
+import { ArrowLeftBold, ArrowRightBold } from "@element-plus/icons-vue";
+const store = useStore();
+
+onMounted(() => {
+  getWeatherData();
+});
+
+const farmInfo = ref({
+  name: "从化荔博园合作社",
+  address: "广东省广州市从化区某某街道",
+});
+
+const tabs = [
+  { key: "temp", label: "温度" },
+  { key: "hum", label: "湿度" },
+  { key: "light", label: "光照" },
+];
+
+const currentTab = ref("temp");
+
+// 简单静态示例数据,后续可替换为接口返回
+const riskMap = ref({
+  temp: [
+    {
+      title: "阴雨寡照",
+      level: "一级",
+      desc: "阴雨寡照湿度大,荔枝易染疾病,需加强田间通风防",
+    },
+    {
+      title: "阴雨寡照",
+      level: "一级",
+      desc: "阴雨寡照湿度大,荔枝易染疾病,需加强田间通风防",
+    },
+    {
+      title: "阴雨寡照",
+      level: "一级",
+      desc: "阴雨寡照湿度大,荔枝易染疾病,需加强田间通风防",
+    },
+  ],
+  hum: [],
+  light: [],
+});
+
+const currentRiskList = computed(() => {
+  return riskMap.value[currentTab.value] || [];
+});
+
+const weatherData = ref(null);
+// 过去7天天气数据
+const pastWeatherData = ref(null);
+const currentChartIndex = ref(0); // 当前显示的图表索引,0表示第一个,1表示第二个
+
+// 切换到上一个图表(向左滑动)
+const prevChart = () => {
+  if (currentChartIndex.value > 0) {
+    currentChartIndex.value--;
+  }
+};
+
+// 切换到下一个图表(向右滑动)
+const nextChart = () => {
+  if (currentChartIndex.value < 1) {
+    currentChartIndex.value++;
+  }
+};
+
+// 获取天气数据
+function getWeatherData() {
+    const point = store.state.home.miniUserLocationPoint;
+    if (!point) {
+        return;
+    }
+    VE_API.old_mini_map.get7d({ point }).then(({ data }) => {
+        if (data && data.daily && data.daily.length > 0) {
+            weatherData.value = data;
+            pastWeatherData.value = data;
+        }
+    }).catch(() => {
+        // 获取天气数据失败,使用默认值
+    });
+}
+</script>
+
+<style scoped lang="scss">
+.weather-detail {
+  width: 100%;
+  height: 100vh;
+  overflow: hidden;
+  box-sizing: border-box;
+  background: #F2F4F5;
+
+  .weather-detail-content {
+    height: calc(100% - 40px);
+    overflow: auto;
+    padding: 10px;
+    box-sizing: border-box;
+  }
+}
+
+.farm-card {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 12px 14px;
+  background: #ffffff;
+  border-radius: 8px;
+  box-shadow: 0 2px 8px rgba(15, 35, 52, 0.06);
+  margin-bottom: 10px;
+
+  .farm-left {
+    flex: 1;
+    min-width: 0;
+  }
+
+  .farm-name-row {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+    margin-bottom: 4px;
+
+    .farm-name {
+      font-size: 16px;
+      font-weight: 600;
+      color: #1d2129;
+    }
+
+    .farm-tag {
+      font-size: 12px;
+      padding: 2px 8px;
+      border-radius: 2px;
+      background: #E8F3FF;
+      color: #2199f8;
+    }
+  }
+
+  .farm-address {
+    font-size: 12px;
+    color: rgba(32, 32, 32, 0.45);
+  }
+
+  .farm-right {
+    margin-right: 10px;
+    font-size: 12px;
+    color: rgba(37, 47, 56, 0.6);
+    flex: none;
+    .farm-point {
+        width: 20px;
+    }
+  }
+}
+
+.weather-chart-container {
+  position: relative;
+  background: #ffffff;
+  border-radius: 8px;
+  padding: 10px;
+  box-shadow: 0 2px 8px rgba(15, 35, 52, 0.06);
+  overflow: hidden;
+
+  .weather-chart-wrapper {
+    width: 100%;
+    overflow: hidden;
+    position: relative;
+  }
+
+  .weather-chart-slider {
+    display: flex;
+    transition: transform 0.3s ease-in-out;
+    width: 200%;
+  }
+
+  .weather-chart-item {
+    flex: 0 0 50%;
+    width: 50%;
+    box-sizing: border-box;
+    padding: 0;
+  }
+
+  .weather-chart {
+    width: 100%;
+    height: 180px;
+  }
+
+  .weather-arrow {
+    position: absolute;
+    top: 50%;
+    transform: translateY(-50%);
+    width: 16px;
+    height: 42px;
+    background: rgba(0, 0, 0, 0.27);
+    border-radius: 2px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+    z-index: 10;
+    transition: background 0.2s;
+
+    &:hover {
+      background: rgba(130, 130, 130, 0.8);
+    }
+
+    &:active {
+      background: rgba(130, 130, 130, 1);
+    }
+
+    .el-icon {
+      color: #ffffff;
+      font-size: 14px;
+    }
+  }
+
+  .weather-arrow-left {
+    left: 0;
+  }
+
+  .weather-arrow-right {
+    right: 0;
+  }
+}
+
+.tab-row {
+  display: inline-flex;
+  gap: 8px;
+  padding: 3px;
+  border-radius: 6px;
+  background: #f2f3f5;
+  margin: 10px 0;
+
+  .tab-item {
+    min-width: 52px;
+    padding: 3px 12px;
+    box-sizing: border-box;
+    text-align: center;
+    font-size: 14px;
+    color: #767676;
+    border-radius: 4px;
+    cursor: pointer;
+    transition: all 0.2s;
+    background: #FFFFFF;
+
+    &.active {
+      background: #2199F8;
+      color: #ffffff;
+      box-shadow: 0 2px 6px rgba(29, 125, 247, 0.45);
+    }
+  }
+}
+
+.risk-list {
+  background: #ffffff;
+  border-radius: 8px;
+  padding: 10px;
+}
+
+.risk-item {
+//   background: #ffffff;
+//   border-radius: 10px;
+//   padding: 10px 12px;
+//   box-shadow: 0 2px 8px rgba(15, 35, 52, 0.03);
+  margin-bottom: 12px;
+
+  .risk-title-row {
+    display: flex;
+    gap: 10px;
+    align-items: center;
+    margin-bottom: 6px;
+
+    .risk-title {
+      font-size: 15px;
+      font-weight: 500;
+      color: #1d2129;
+    }
+
+    .risk-level {
+      font-size: 12px;
+      padding: 2px 10px;
+      border-radius: 2px;
+      background: #E8F3FF;
+      color: #2199F8;
+    }
+  }
+
+  .risk-desc {
+    font-size: 13px;
+    color: #4e5969;
+    line-height: 1.5;
+  }
+}
+</style>
+

+ 718 - 0
src/views/old_mini/work_detail/index.vue

@@ -0,0 +1,718 @@
+<template>
+    <div class="work-detail">
+        <custom-header name="农事详情" :showClose="false" isGoBack @goback="handleBack" />
+
+        <div class="work-detail-content">
+            <!-- 顶部状态 -->
+            <div class="content-status">
+                <div class="status-l">
+                    <div class="status-title">{{ statusText }}</div>
+                    <div class="status-sub" v-if="triggerDateText">
+                        预计触发时间 {{ triggerDateText }}
+                    </div>
+                </div>
+            </div>
+
+            <div class="work-wrap">
+                <!-- 农事组信息 -->
+                <div class="box-wrap group-info group-box">
+                    <div class="group-name">
+                        农事组:
+                        <span class="group-name-text">{{ detail.farmWorkName || detail.farmWorkLibName || "--" }}</span>
+                    </div>
+                </div>
+
+                <!-- 每一段农事 -->
+                <div v-for="(prescription, index) in stageList" :key="index" class="box-wrap stage-card">
+                    <div class="stage-header">
+                        <div class="stage-title">{{ getStageTitle(index, prescription) }}</div>
+                    </div>
+
+                    <div class="stage-info">
+                        <div class="form-item">
+                            <div class="item-name">农事目的</div>
+                            <div class="item-text">
+                                {{ detail.purpose || prescription.name || "--" }}
+                            </div>
+                        </div>
+                        <div class="form-item">
+                            <div class="item-name">农事时间</div>
+                            <div class="item-text">
+                                {{ detail.intervelTime ? `间隔 ${detail.intervelTime} 天后 执行` : "--" }}
+                            </div>
+                        </div>
+                        <div class="form-item">
+                            <div class="item-name">执行区域</div>
+                            <div class="item-text light-text">
+                                桂味种植区域
+                            </div>
+                        </div>
+                        <div class="form-item">
+                            <div class="item-name">注意事项</div>
+                            <div class="item-text">
+                                {{ detail.remark || "--" }}
+                            </div>
+                        </div>
+                        <div class="form-item">
+                            <div class="item-name">药肥处方</div>
+                        </div>
+                    </div>
+
+                    <!-- 执行方式 -->
+                    <div class="stage-tabs">
+                        <div
+                            v-for="tab in executionTabs"
+                            :key="tab.value"
+                            class="tab-pill"
+                            :class="{ active: getStageExecutionMethod(index) === tab.value }"
+                            @click="changeExecutionMethod(index, tab.value)"
+                        >
+                            {{ tab.label }}
+                        </div>
+                    </div>
+
+                    <!-- 药物处方表 -->
+                    <div class="prescription-wrap"
+                        v-if="prescription.pesticideList && prescription.pesticideList.length">
+                        <div class="prescription-table">
+                            <div class="table-header">
+                                <div class="col col-type">使用功效</div>
+                                <div class="col col-name">药肥名称</div>
+                                <div class="col col-ratio">药肥配比</div>
+                            </div>
+
+                            <div
+                                v-for="(item, i) in prescription.pesticideList"
+                                :key="i"
+                                class="table-row"
+                            >
+                                <div class="col col-type">
+                                    {{ item.typeName || "--" }}
+                                </div>
+                                <div class="col col-name">
+                                    {{ item.name || item.pesticideFertilizerName || "--" }}
+                                </div>
+                                <div class="col col-ratio">
+                                    {{ getPesticideParam(item, index)?.ratio || "--" }}倍
+                                </div>
+                            </div>
+                        </div>
+
+                        <div v-if="hasRemark(prescription, index)" class="prescription-remark">
+                            <span
+                                v-for="(item, idx) in [prescription.pesticideList[0]]"
+                                :key="idx"
+                            >
+                                <template v-if="getParamRemark(item, index)">
+                                    {{ getParamRemark(item, index) }}
+                                    <br />
+                                </template>
+                            </span>
+                        </div>
+                    </div>
+                </div>
+
+                <!-- 底部按钮 -->
+                <div class="fixed-btn-wrap">
+                    <div class="fixed-btn" @click="handleConvert">
+                        转发农事
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import customHeader from "@/components/customHeader.vue";
+import { ref, computed, onActivated } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { formatDate } from "@/common/commonFun";
+
+const route = useRoute();
+const router = useRouter();
+
+const detail = ref({
+    "consequenceText": "",
+    "id": null,
+    "reCheckText": "",
+    "orderId": null,
+    "farmWorkArrangeId": null,
+    "farmName": "",
+    "farmPoint": "",
+    "area": null,
+    "expert": null,
+    "orderStatus": null,
+    "activeStatus": null,
+    "flowStatus": null,
+    "farmId": null,
+    "regionId": null,
+    "farmMiniUserId": null,
+    "farmMiniUserName": "",
+    "speciesId": "1",
+    "speciesName": "",
+    "agriculturalId": null,
+    "agriculturalIcon": "",
+    "farmWorkId": "793434539249635329",
+    "farmWorkLibId": "793434539249635329",
+    "farmWorkLibName": "蒂蛀虫防治",
+    "farmWorkName": "蒂蛀虫防治",
+    "expertName": "",
+    "expertUserName": "",
+    "expertIcon": "",
+    "expertUserIcon": "",
+    "icon": null,
+    "indexName": "",
+    "indexChart": [],
+    "executeDate": "2025-08-15",
+    "intervelTime": 10,
+    "executeDeadlineDate": null,
+    "expectedExecuteDate": null,
+    "finishDate": null,
+    "checkDate": null,
+    "beforeExecuteDate": null,
+    "indexJson": "",
+    "expertPrescription": "",
+    "code": "793434539249635328",
+    "condition": "",
+    "solarName": "",
+    "reCheck": null,
+    "remark": "严禁低温寒潮、霜冻、倒春寒前24小时内追肥,避免根系、叶片受刺激引发冻害、肥害。",
+    "menu": null,
+    "num": null,
+    "purpose": "营养",
+    "type": 1,
+    "farmWorkType": 2,
+    "farmWorkTypeName": "",
+    "execute": null,
+    "updateDate0": null,
+    "updateDate1": null,
+    "updateDate2": null,
+    "updateDate3": null,
+    "updateDate4": null,
+    "updateDate5": null,
+    "updateDate6": null,
+    "confirmPicture": [],
+    "executeEvidence": [],
+    "reviewImage": [],
+    "reviewImage2": [],
+    "reviewDate": null,
+    "reviewDate2": null,
+    "serviceRegion": "",
+    "usageMode": "",
+    "serviceMain": "",
+    "executeMain": "",
+    "storeShortName": "",
+    "weatherWarningMsg": "",
+    "userEvaluation": null,
+    "executeBlueZones": [],
+    "isMaster": null,
+    "isEdit": null,
+    "selfExec": null,
+    "defaultFarmWork": null,
+    "isPublic": null,
+    "users": [],
+    "groupList": [
+        {
+            "name": "蒂蛀虫防治",
+            "pesticideList": [
+                {
+                    "code": "1009",
+                    "name": "化学水溶肥",
+                    "typeName": "氮肥",
+                    "params": [
+                        {
+                            "dosage": "50",
+                            "executionMethod": 1,
+                            "ratio": "30000",
+                            "remark": "飞行参数设置为***,飞行速度设置为飞行参数设置为***,飞行速度设置为"
+                        },
+                        {
+                            "dosage": "21",
+                            "executionMethod": 2,
+                            "ratio": "221",
+                            "remark": "rengong"
+                        },
+                        {
+                            "dosage": "11",
+                            "executionMethod": 3,
+                            "ratio": "111",
+                            "remark": "dimian"
+                        }
+                    ]
+                },
+                {
+                    "code": "1010",
+                    "name": "化学水溶肥2",
+                    "typeName": "营养",
+                    "params": [
+                        {
+                            "dosage": "0.5",
+                            "executionMethod": 1,
+                            "ratio": "30000",
+                            "remark": "zhibaoji"
+                        },
+                        {
+                            "dosage": "22",
+                            "executionMethod": 2,
+                            "ratio": "222",
+                            "remark": "rengong"
+                        },
+                        {
+                            "dosage": "12",
+                            "executionMethod": 3,
+                            "ratio": "112",
+                            "remark": "dimian"
+                        }
+                    ]
+                },
+                {
+                    "code": "1011",
+                    "name": "化学水溶肥3",
+                    "typeName": "营养",
+                    "params": [
+                        {
+                            "dosage": "60",
+                            "executionMethod": 1,
+                            "ratio": "30000",
+                            "remark": "zhibaoji"
+                        },
+                        {
+                            "dosage": "23",
+                            "executionMethod": 2,
+                            "ratio": "223",
+                            "remark": "rengong"
+                        },
+                        {
+                            "dosage": "13",
+                            "executionMethod": 3,
+                            "ratio": "113",
+                            "remark": "dimian"
+                        }
+                    ]
+                }
+            ],
+        },
+        {
+            "name": "蒂蛀虫防治",
+            "pesticideList": [
+                {
+                    "code": "1009",
+                    "name": "化学水溶肥22",
+                    "typeName": "氮肥",
+                    "params": [
+                        {
+                            "dosage": "50",
+                            "executionMethod": 1,
+                            "ratio": "30000",
+                            "remark": "zhibaoji"
+                        },
+                        {
+                            "dosage": "21",
+                            "executionMethod": 2,
+                            "ratio": "221",
+                            "remark": "rengong"
+                        },
+                        {
+                            "dosage": "11",
+                            "executionMethod": 3,
+                            "ratio": "111",
+                            "remark": "dimian"
+                        }
+                    ]
+                },
+                {
+                    "code": "1010",
+                    "name": "化学水溶肥222",
+                    "typeName": "营养",
+                    "params": [
+                        {
+                            "dosage": "0.5",
+                            "executionMethod": 1,
+                            "ratio": "30000",
+                            "remark": "zhibaoji"
+                        },
+                        {
+                            "dosage": "22",
+                            "executionMethod": 2,
+                            "ratio": "222",
+                            "remark": "rengong"
+                        },
+                        {
+                            "dosage": "12",
+                            "executionMethod": 3,
+                            "ratio": "112",
+                            "remark": "dimian"
+                        }
+                    ]
+                },
+                {
+                    "code": "1011",
+                    "name": "化学水溶肥223",
+                    "typeName": "营养",
+                    "params": [
+                        {
+                            "dosage": "60",
+                            "executionMethod": 1,
+                            "ratio": "30000",
+                            "remark": "zhibaoji"
+                        },
+                        {
+                            "dosage": "23",
+                            "executionMethod": 2,
+                            "ratio": "223",
+                            "remark": "rengong"
+                        },
+                        {
+                            "dosage": "13",
+                            "executionMethod": 3,
+                            "ratio": "113",
+                            "remark": "dimian"
+                        }
+                    ]
+                }
+            ],
+        },
+    ],
+    "needReview": null,
+    "conditionList": [],
+    "actualAgriculturalInput": null,
+    "actualFarmServiceInput": null,
+    "actualTotalInput": null,
+    "executeName": "",
+    "executorIcon": "",
+    "executorUserId": null,
+    "postId": "806490699515039744"
+});
+
+// 执行方式 Tab 配置
+const executionTabs = [
+    { label: "植保机", value: 1 },
+    { label: "人工手持", value: 2 },
+    { label: "地面机械", value: 3 }
+];
+// 每一段农事的当前执行方式(索引 -> 执行方式),默认 1:植保机
+const stageExecutionMethods = ref({});
+
+const statusText = computed(() => {
+    // 简单根据 flowStatus 判断,默认“待触发”
+    if (detail.value.flowStatus === 2) return "执行中";
+    if (detail.value.flowStatus === 3) return "已完成";
+    return "待触发";
+});
+
+const triggerDateText = computed(() => {
+    if (!detail.value.executeDate) return "";
+    const d = formatDate(detail.value.executeDate);
+    return d.replace(/-/g, ".");
+});
+
+// const displayExecuteDate = computed(() => {
+//     if (!detail.value.executeDate) return "";
+//     return formatDate(detail.value.executeDate);
+// });
+
+const stageList = computed(() => detail.value.groupList || []);
+
+const getStageTitle = (index, prescription) => {
+    const numMap = ["一", "二", "三", "四", "五", "六", "七"];
+    const prefix = numMap[index] ? `第${numMap[index]}段` : `第${index + 1}段`;
+    const name = detail.value.farmWorkName || prescription?.name || "";
+    return name ? `${prefix}${name}` : prefix;
+};
+
+const hasRemark = (prescription, stageIndex) => {
+    if (!prescription?.pesticideList || !Array.isArray(prescription.pesticideList)) return false;
+    const currentMethod = getStageExecutionMethod(stageIndex);
+    return prescription.pesticideList.some((item) => {
+        if (!item.params || !Array.isArray(item.params)) return false;
+        const p = item.params.find((param) => param.executionMethod === currentMethod);
+        return !!(p && p.remark);
+    });
+};
+
+const handleBack = () => {
+    router.back();
+};
+
+const handleConvert = () => {
+    // 预留“转成农事”逻辑,后续接入实际接口
+};
+
+// 获取当前段的执行方式
+const getStageExecutionMethod = (stageIndex) => {
+    const val = stageExecutionMethods.value[stageIndex];
+    return val || 1;
+};
+
+// 根据当前执行方式,获取对应的参数(配比、单亩用量、备注)
+const getPesticideParam = (item, stageIndex) => {
+    if (!item?.params || !Array.isArray(item.params)) return null;
+    const currentMethod = getStageExecutionMethod(stageIndex);
+    return (
+        item.params.find((param) => param.executionMethod === currentMethod) || null
+    );
+};
+
+const getParamRemark = (item, stageIndex) => {
+    const param = getPesticideParam(item, stageIndex);
+    console.log('param', param?.remark);
+    return param?.remark || item.remark || "";
+};
+
+const changeExecutionMethod = (stageIndex, value) => {
+    stageExecutionMethods.value = {
+        ...stageExecutionMethods.value,
+        [stageIndex]: value
+    };
+};
+</script>
+
+<style scoped lang="scss">
+.work-detail {
+    height: 100vh;
+    background: #f2f3f5;
+    display: flex;
+    flex-direction: column;
+
+    .work-detail-content {
+        flex: 1;
+        overflow: auto;
+    }
+}
+
+.content-status {
+    position: relative;
+    padding: 21px 12px 0 12px;
+    color: #fff;
+    z-index: 1;
+    height: 100px;
+    box-sizing: border-box;
+
+    &::after {
+        content: "";
+        z-index: -1;
+        position: absolute;
+        left: 0;
+        top: 0;
+        height: 100px;
+        background: #C7C7C7;
+        // background: #FF953D;
+        width: 100%;
+    }
+
+    .status-l {
+        .status-title {
+            font-size: 22px;
+        }
+
+        .status-sub {
+            margin-top: 2px;
+            font-size: 14px;
+        }
+    }
+}
+
+.work-wrap {
+    position: relative;
+    top: -12px;
+    padding: 0 12px 12px;
+    z-index: 2;
+    margin-bottom: 60px;
+}
+
+.box-wrap {
+    background: #ffffff;
+    border-radius: 8px;
+    padding: 14px 10px 10px 10px;
+    box-shadow: 0 2px 8px rgba(15, 35, 52, 0.06);
+}
+
+.group-info {
+    margin-bottom: 10px;
+
+    &.group-box {
+        padding: 16px 10px;
+
+        .group-name {
+            font-size: 16px;
+            color: #000;
+
+            .group-name-text {
+                color: #000;
+            }
+        }
+    }
+
+    .group-name {
+        font-size: 14px;
+        color: rgba(0, 0, 0, 0.2);
+
+        .group-name-text {
+            color: #767676;
+        }
+    }
+
+    .group-sub {
+        margin-top: 6px;
+        font-size: 12px;
+        color: rgba(0, 0, 0, 0.45);
+        line-height: 1.5;
+    }
+}
+
+.stage-card {
+    margin-top: 10px;
+
+    .stage-header {
+        padding-bottom: 12px;
+
+        .stage-title {
+            font-size: 16px;
+            color: #000;
+        }
+    }
+
+    .stage-info {
+        padding: 8px 0 2px;
+        border-top: 1px solid #f5f5f5;
+    }
+}
+
+.form-item {
+    display: flex;
+    font-size: 14px;
+    color: #767676;
+    margin-top: 4px;
+
+    .item-name {
+        padding-right: 26px;
+        color: rgba(0, 0, 0, 0.2);
+    }
+
+    .item-text {
+        flex: 1;
+        line-height: 21px;
+
+        &.light-text {
+            color: #2199F8;
+        }
+    }
+}
+
+.stage-tabs {
+    display: inline-flex;
+    gap: 8px;
+    margin-top: 8px;
+
+    .tab-pill {
+        padding: 0 8px;
+        font-size: 14px;
+        text-align: center;
+        border-radius: 2px;
+        height: 28px;
+        line-height: 28px;
+        color: #767676;
+        background: rgba(171, 171, 171, 0.1);
+
+        &.active {
+            background: rgba(33, 153, 248, 0.1);
+            color: #2199F8;
+        }
+    }
+}
+
+.prescription-wrap {
+    margin-top: 10px;
+    overflow: hidden;
+
+    .prescription-title {
+        padding: 8px 10px;
+        font-size: 13px;
+        font-weight: 500;
+        border-bottom: 1px solid rgba(225, 225, 225, 0.6);
+    }
+}
+
+.prescription-table {
+    font-size: 12px;
+    text-align: center;
+    border-radius: 6px;
+    border: 1px solid rgba(225, 225, 225, 0.6);
+
+    .table-header {
+        display: flex;
+        background: rgba(171, 171, 171, 0.1);
+        padding: 9px 6px;
+        color: #767676;
+    }
+
+    .table-row {
+        display: flex;
+        padding: 12px 6px;
+        border-bottom: 1px solid rgba(0, 0, 0, 0.08);
+        color: rgba(0, 0, 0, 0.76);
+
+        &:last-child {
+            border-bottom: none;
+        }
+    }
+
+    .col {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        padding: 0 2px;
+    }
+
+    .col-type {
+        width: 56px;
+    }
+
+    .col-name {
+        flex: 1;
+    }
+
+    .col-ratio {
+        width: 64px;
+    }
+
+    .col-dose {
+        width: 64px;
+    }
+}
+
+.prescription-remark {
+    margin-top: 8px;
+    padding: 7px 10px;
+    border-radius: 6px;
+    color: #767676;
+    background: rgba(171, 171, 171, 0.1);
+    line-height: 21px;
+}
+
+.fixed-btn-wrap {
+    display: flex;
+    justify-content: center;
+    position: fixed;
+    bottom: 0px;
+    left: 0;
+    right: 0;
+    background: #fff;
+    padding: 10px 12px;
+    box-sizing: border-box;
+    // box-shadow: 0 -2px 8px rgba(15, 35, 52, 0.06);
+    box-shadow: 2px 2px 4.5px 0px #00000066;
+
+    .fixed-btn {
+        min-width: 110px;
+        height: 40px;
+        line-height: 40px;
+        text-align: center;
+        border-radius: 20px;
+        background: linear-gradient(180deg, #70bffe, #2199f8);
+        color: #ffffff;
+        font-size: 14px;
+    }
+}
+</style>