|
|
@@ -1,29 +1,524 @@
|
|
|
<template>
|
|
|
- <div class="page-placeholder">
|
|
|
- <h2>种植方案</h2>
|
|
|
- <p>页面内容区域,后续在此完善业务。</p>
|
|
|
+ <div class="planting-page">
|
|
|
+ <div class="page-card">
|
|
|
+ <!-- 顶部:Tab + 操作 -->
|
|
|
+ <div class="page-header">
|
|
|
+ <div class="page-tabs">
|
|
|
+ <div
|
|
|
+ v-for="tab in tabs"
|
|
|
+ :key="tab.value"
|
|
|
+ class="page-tabs__item"
|
|
|
+ :class="{ 'is-active': activeTab === tab.value }"
|
|
|
+ @click="activeTab = tab.value"
|
|
|
+ >
|
|
|
+ {{ tab.label }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <el-button type="warning" class="btn-add" @click="onAddDevice">
|
|
|
+ 新增设备
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 筛选区 -->
|
|
|
+ <div class="filter-panel">
|
|
|
+ <div class="filter-row">
|
|
|
+ <span class="filter-label">区域:</span>
|
|
|
+ <div class="filter-content region-selects">
|
|
|
+ <el-select
|
|
|
+ v-model="filters.province"
|
|
|
+ placeholder="选择省份"
|
|
|
+ clearable
|
|
|
+ class="region-select"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in provinceOptions"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ <el-select
|
|
|
+ v-model="filters.city"
|
|
|
+ placeholder="选择城市"
|
|
|
+ clearable
|
|
|
+ class="region-select"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in cityOptions"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="filter-row">
|
|
|
+ <span class="filter-label">品类:</span>
|
|
|
+ <div class="filter-content tag-list">
|
|
|
+ <button
|
|
|
+ v-for="(item, idx) in categoryOptions"
|
|
|
+ :key="`category-${idx}`"
|
|
|
+ type="button"
|
|
|
+ class="filter-tag"
|
|
|
+ :class="{ 'is-active': filters.categoryIndex === idx }"
|
|
|
+ @click="filters.categoryIndex = idx"
|
|
|
+ >
|
|
|
+ {{ item }}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="filter-row">
|
|
|
+ <span class="filter-label">品种:</span>
|
|
|
+ <div class="filter-content tag-list">
|
|
|
+ <button
|
|
|
+ v-for="(item, idx) in varietyOptions"
|
|
|
+ :key="`variety-${idx}`"
|
|
|
+ type="button"
|
|
|
+ class="filter-tag"
|
|
|
+ :class="{ 'is-active': filters.varietyIndex === idx }"
|
|
|
+ @click="filters.varietyIndex = idx"
|
|
|
+ >
|
|
|
+ {{ item }}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 方案表格 -->
|
|
|
+ <div class="table-wrap">
|
|
|
+ <el-table
|
|
|
+ :data="tableData"
|
|
|
+ border
|
|
|
+ class="scheme-table"
|
|
|
+ :header-cell-style="headerCellStyle"
|
|
|
+ :cell-style="{ verticalAlign: 'top' }"
|
|
|
+ >
|
|
|
+ <el-table-column prop="name" label="农事名称" min-width="110" fixed>
|
|
|
+ <template #default="{ row }">
|
|
|
+ <span class="cell-name">{{ row.name }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+
|
|
|
+ <el-table-column label="农事类型" min-width="200">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <div class="link-group">
|
|
|
+ <a
|
|
|
+ v-for="(item, idx) in row.types"
|
|
|
+ :key="idx"
|
|
|
+ class="cell-link"
|
|
|
+ href="javascript:;"
|
|
|
+ >{{ item }}</a>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+
|
|
|
+ <el-table-column prop="trigger" label="触发条件" min-width="160">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <p class="cell-text">{{ row.trigger }}</p>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+
|
|
|
+ <el-table-column label="药肥处方" min-width="280">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <div class="prescription">
|
|
|
+ <div class="prescription__title">{{ row.prescription.category }}</div>
|
|
|
+ <div
|
|
|
+ v-for="(line, idx) in row.prescription.lines"
|
|
|
+ :key="idx"
|
|
|
+ class="prescription__line"
|
|
|
+ >
|
|
|
+ {{ line }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+
|
|
|
+ <el-table-column label="执行规程" align="center">
|
|
|
+ <el-table-column label="执行窗口" min-width="140">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <p class="cell-text">{{ row.execute.window }}</p>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="执行设备" min-width="120">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <div class="link-group link-group--col">
|
|
|
+ <a
|
|
|
+ v-for="(item, idx) in row.execute.devices"
|
|
|
+ :key="idx"
|
|
|
+ class="cell-link"
|
|
|
+ href="javascript:;"
|
|
|
+ >{{ item }}</a>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="注意事项" min-width="160">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <p class="cell-text">{{ row.execute.notes }}</p>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+
|
|
|
+ <el-table-column label="复核规程" align="center">
|
|
|
+ <el-table-column label="复核时间" min-width="110">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <p class="cell-text">{{ row.review.time }}</p>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="复核标准" min-width="160">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <p class="cell-text">{{ row.review.standard }}</p>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 底部操作 -->
|
|
|
+ <div class="page-footer">
|
|
|
+ <el-button type="warning" plain class="btn-copy" @click="onCopyScheme">
|
|
|
+ 复制为我的方案
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
+import { reactive, ref } from "vue";
|
|
|
+import { ElMessage } from "element-plus";
|
|
|
+
|
|
|
+const tabs = [
|
|
|
+ { label: "种植方案", value: "scheme" },
|
|
|
+ { label: "我的方案", value: "mine" },
|
|
|
+];
|
|
|
+const activeTab = ref("scheme");
|
|
|
+
|
|
|
+const filters = reactive({
|
|
|
+ province: "",
|
|
|
+ city: "",
|
|
|
+ categoryIndex: 0,
|
|
|
+ varietyIndex: 0,
|
|
|
+});
|
|
|
+
|
|
|
+const provinceOptions = [
|
|
|
+ { label: "广东省", value: "guangdong" },
|
|
|
+ { label: "广西壮族自治区", value: "guangxi" },
|
|
|
+ { label: "海南省", value: "hainan" },
|
|
|
+];
|
|
|
+
|
|
|
+const cityOptions = [
|
|
|
+ { label: "广州市", value: "guangzhou" },
|
|
|
+ { label: "深圳市", value: "shenzhen" },
|
|
|
+ { label: "茂名市", value: "maoming" },
|
|
|
+];
|
|
|
+
|
|
|
+const categoryOptions = ["荔枝", "水稻", "水稻", "水稻", "水稻", "水稻", "水稻"];
|
|
|
+const varietyOptions = ["妃子笑", "桂味", "桂味", "桂味", "桂味", "桂味", "桂味", "桂味", "桂味", "桂味"];
|
|
|
+
|
|
|
+const placeholderText =
|
|
|
+ "触发条件触发条件触发条件触发条件触发条件触发条件触发条件触发条件触发条件触发条件";
|
|
|
+
|
|
|
+const tableData = ref([
|
|
|
+ {
|
|
|
+ name: "播前基肥",
|
|
|
+ types: ["标准农事", "日常营养", "水肥类"],
|
|
|
+ trigger: placeholderText,
|
|
|
+ prescription: {
|
|
|
+ category: "营养类",
|
|
|
+ lines: [
|
|
|
+ "砂土: 产品名称/用量/亩 使用次数",
|
|
|
+ "粘土: 产品名称/用量/亩 使用次数",
|
|
|
+ "壤土: 产品名称/用量/亩 使用次数",
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ execute: {
|
|
|
+ window: "生育期起始-生育期结束",
|
|
|
+ devices: ["农机设备一", "农机设备二", "农机设备三"],
|
|
|
+ notes: placeholderText,
|
|
|
+ },
|
|
|
+ review: {
|
|
|
+ time: "执行后 7 天",
|
|
|
+ standard: placeholderText,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "播前基肥",
|
|
|
+ types: ["标准农事", "日常营养", "水肥类"],
|
|
|
+ trigger: placeholderText,
|
|
|
+ prescription: {
|
|
|
+ category: "营养类",
|
|
|
+ lines: [
|
|
|
+ "砂土: 产品名称/用量/亩 使用次数",
|
|
|
+ "粘土: 产品名称/用量/亩 使用次数",
|
|
|
+ "壤土: 产品名称/用量/亩 使用次数",
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ execute: {
|
|
|
+ window: "生育期起始-生育期结束",
|
|
|
+ devices: ["农机设备一", "农机设备二", "农机设备三"],
|
|
|
+ notes: placeholderText,
|
|
|
+ },
|
|
|
+ review: {
|
|
|
+ time: "执行后 7 天",
|
|
|
+ standard: placeholderText,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "播前基肥",
|
|
|
+ types: ["标准农事", "日常营养", "水肥类"],
|
|
|
+ trigger: placeholderText,
|
|
|
+ prescription: {
|
|
|
+ category: "营养类",
|
|
|
+ lines: [
|
|
|
+ "砂土: 产品名称/用量/亩 使用次数",
|
|
|
+ "粘土: 产品名称/用量/亩 使用次数",
|
|
|
+ "壤土: 产品名称/用量/亩 使用次数",
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ execute: {
|
|
|
+ window: "生育期起始-生育期结束",
|
|
|
+ devices: ["农机设备一", "农机设备二", "农机设备三"],
|
|
|
+ notes: placeholderText,
|
|
|
+ },
|
|
|
+ review: {
|
|
|
+ time: "执行后 7 天",
|
|
|
+ standard: placeholderText,
|
|
|
+ },
|
|
|
+ },
|
|
|
+]);
|
|
|
+
|
|
|
+const headerCellStyle = {
|
|
|
+ background: "#f5f7fa",
|
|
|
+ color: "#606266",
|
|
|
+ fontWeight: 500,
|
|
|
+ textAlign: "center",
|
|
|
+};
|
|
|
+
|
|
|
+const onAddDevice = () => {
|
|
|
+ ElMessage.info("新增设备功能待接入");
|
|
|
+};
|
|
|
+
|
|
|
+const onCopyScheme = () => {
|
|
|
+ ElMessage.success("已复制为我的方案");
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.page-placeholder {
|
|
|
+$primary: $warning-color;
|
|
|
+$primary-light: mix(#fff, $warning-color, 90%);
|
|
|
+$link: #409eff;
|
|
|
+$text: #303133;
|
|
|
+$text-secondary: #606266;
|
|
|
+$border: #E7E7E7;
|
|
|
+
|
|
|
+.planting-page {
|
|
|
box-sizing: border-box;
|
|
|
min-height: 100%;
|
|
|
- padding: 24px;
|
|
|
- background: #fff;
|
|
|
+ padding: 25px;
|
|
|
+ .page-card {
|
|
|
+ background: #fff;
|
|
|
+ padding: 10px;
|
|
|
+ .page-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ border-bottom: 1px solid $border;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.page-tabs {
|
|
|
+ display: flex;
|
|
|
+ gap: 32px;
|
|
|
+
|
|
|
+ &__item {
|
|
|
+ position: relative;
|
|
|
+ padding: 16px 0 14px;
|
|
|
+ font-size: 15px;
|
|
|
+ color: $text-secondary;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: color 0.2s;
|
|
|
+ user-select: none;
|
|
|
|
|
|
- h2 {
|
|
|
- margin: 0 0 8px;
|
|
|
- font-size: 20px;
|
|
|
- color: #303133;
|
|
|
+ &:hover {
|
|
|
+ color: $primary;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.is-active {
|
|
|
+ color: $primary;
|
|
|
+ font-weight: 500;
|
|
|
+
|
|
|
+ &::after {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ height: 3px;
|
|
|
+ background: $primary;
|
|
|
+ border-radius: 2px 2px 0 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+.btn-add {
|
|
|
+ height: 32px;
|
|
|
+ padding: 0 16px;
|
|
|
+ font-size: 13px;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-panel {
|
|
|
+ padding: 20px 0 8px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ gap: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-label {
|
|
|
+ flex-shrink: 0;
|
|
|
+ width: 42px;
|
|
|
+ line-height: 32px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: $text;
|
|
|
+ text-align: right;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-content {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.region-selects {
|
|
|
+ display: flex;
|
|
|
+ gap: 12px;
|
|
|
+}
|
|
|
|
|
|
- p {
|
|
|
- margin: 0;
|
|
|
- color: #909399;
|
|
|
+.region-select {
|
|
|
+ width: 160px;
|
|
|
+}
|
|
|
+
|
|
|
+.tag-list {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.filter-tag {
|
|
|
+ appearance: none;
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
+ background: #f5f7fa;
|
|
|
+ color: $text-secondary;
|
|
|
+ height: 32px;
|
|
|
+ padding: 0 16px;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 13px;
|
|
|
+ line-height: 30px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.2s;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ border-color: $primary;
|
|
|
+ color: $primary;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.is-active {
|
|
|
+ background: $primary-light;
|
|
|
+ border-color: $primary;
|
|
|
+ color: $primary;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.table-wrap {
|
|
|
+ flex: 1;
|
|
|
+ min-height: 0;
|
|
|
+ overflow: auto;
|
|
|
+}
|
|
|
+
|
|
|
+.scheme-table {
|
|
|
+ width: 100%;
|
|
|
+
|
|
|
+ :deep(.el-table__header th) {
|
|
|
+ font-size: 13px;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-table__body td) {
|
|
|
+ padding: 14px 0;
|
|
|
}
|
|
|
+
|
|
|
+ :deep(.el-table__cell) {
|
|
|
+ vertical-align: top;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.cell-name {
|
|
|
+ font-weight: 600;
|
|
|
+ color: $text;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.cell-text {
|
|
|
+ margin: 0;
|
|
|
+ font-size: 13px;
|
|
|
+ line-height: 1.6;
|
|
|
+ color: $text-secondary;
|
|
|
+ word-break: break-all;
|
|
|
+}
|
|
|
+
|
|
|
+.link-group {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 8px 12px;
|
|
|
+
|
|
|
+ &--col {
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 6px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.cell-link {
|
|
|
+ color: $link;
|
|
|
+ font-size: 13px;
|
|
|
+ text-decoration: none;
|
|
|
+ line-height: 1.5;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ text-decoration: underline;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.prescription {
|
|
|
+ font-size: 13px;
|
|
|
+ line-height: 1.7;
|
|
|
+ color: $text-secondary;
|
|
|
+
|
|
|
+ &__title {
|
|
|
+ color: $text;
|
|
|
+ margin-bottom: 2px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &__line {
|
|
|
+ word-break: break-all;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.page-footer {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ padding-top: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-copy {
|
|
|
+ height: 36px;
|
|
|
+ padding: 0 20px;
|
|
|
+ font-size: 14px;
|
|
|
}
|
|
|
</style>
|