<template>
#set($designed = $hasCurrentFrontendPageDesign)
#set($queryColumns = $columns)
#set($tableColumns = $columns)
#set($formColumns = $columns)
#set($cardColumns = $columns)
#set($cardTitleColumn = false)
#set($cardImageColumn = false)
#set($showAdd = false)
#set($showBatchDelete = false)
#set($showView = false)
#set($showEdit = false)
#set($showDelete = false)
#set($isCardListLayout = false)
#set($isSplitListLayout = false)
#set($showQuery = true)
#set($showToolbar = true)
#set($showForm = true)
#set($renderForm = true)
#set($currentUserOnly = false)
#set($toolbarBusinessActions = $pageDesignToolbarBusinessActions)
#set($rowBusinessActions = $pageDesignRowBusinessActions)
#set($allPageBusinessActions = $pageDesignBusinessActions)
#set($hasToolbarBusinessActions = $hasPageDesignToolbarBusinessActions)
#set($hasRowBusinessActions = $hasPageDesignRowBusinessActions)
#set($topBusinessBlocks = $pageDesignTopBusinessBlocks)
#set($bottomBusinessBlocks = $pageDesignBottomBusinessBlocks)
#set($embeddedBusinessBlocks = $pageDesignEmbeddedBusinessBlocks)
#if($allowAdd == '1')
#set($showAdd = true)
#end
#if($allowRemove == '1')
#set($showBatchDelete = true)
#set($showDelete = true)
#end
#if($allowEdit == '1')
#set($showEdit = true)
#end
#if($designed)
#set($queryColumns = $pageDesignQueryColumns)
#set($tableColumns = $pageDesignTableColumns)
#set($formColumns = $pageDesignFormColumns)
#set($cardColumns = $pageDesignCardColumns)
#set($cardTitleColumn = $pageDesignCardTitleColumn)
#set($cardImageColumn = $pageDesignCardImageColumn)
#set($showAdd = $pageDesignAllowAdd)
#set($showBatchDelete = $pageDesignAllowBatchDelete)
#set($showView = $pageDesignAllowView)
#set($showEdit = $pageDesignAllowEdit)
#set($showDelete = $pageDesignAllowDelete)
#set($isCardListLayout = $pageDesignIsCardList)
#set($isSplitListLayout = $pageDesignIsSplitList)
#set($showQuery = $pageDesignShowQuery)
#set($showToolbar = $pageDesignShowToolbar)
#set($showForm = $pageDesignShowForm)
#set($currentUserOnly = $pageDesignIsCurrentUserList)
#end
#if(!$showToolbar)
#set($showAdd = false)
#set($showBatchDelete = false)
#end
#set($renderForm = $showForm)
#if($showAdd || $showEdit)
#set($renderForm = true)
#end
  <section class="portal-page">
#if($hasPageDesignTopBusinessBlocks)
    <section class="embedded-business-blocks top-business-blocks">
#foreach($block in $topBusinessBlocks)
      <${block.componentName} />
#end
    </section>
#end

    <section class="content-board">
      <div class="feature-card">
        <div class="feature-illustration" aria-hidden="true">
          <div class="device-face">
            <span></span>
            <span></span>
          </div>
        </div>
        <div class="feature-copy">
          <span>精选推荐</span>
          <h2>${functionName}</h2>
          <p>围绕资源管理、活动公告和玩家社区内容，快速维护当前模块的数据。</p>
        </div>
      </div>

      <aside class="notice-panel">
        <div class="notice-tabs">
          <button
            v-for="tab in noticeTabs"
            :key="tab"
            type="button"
            :class="{ active: activeTab === tab }"
            @click="activeTab = tab">
            {{ tab }}
          </button>
        </div>
        <ul class="notice-list">
          <li v-for="notice in notices" :key="notice.title">
            <strong>{{ notice.title }}</strong>
            <span><i class="el-icon-time"></i>{{ notice.time }}</span>
          </li>
        </ul>
      </aside>
    </section>

    <section class="data-panel#if($isSplitListLayout) split-data-panel#end">
      <div class="panel-heading">
        <div>
          <span class="section-kicker">资源数据</span>
          <h2>${functionName}管理</h2>
        </div>
        <div class="panel-actions">
          #if($showToolbar)
          #if($showAdd)
          <el-button type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
          #end
          #if($showBatchDelete)
          <el-popconfirm
            confirm-button-text="确定"
            cancel-button-text="取消"
            icon="el-icon-info"
            icon-color="red"
            title="确定批量删除选中的数据吗？"
            @confirm="delBatch">
            <el-button slot="reference" type="danger" icon="el-icon-delete">批量删除</el-button>
          </el-popconfirm>
          #end
          #foreach($action in $toolbarBusinessActions)
          <el-button type="primary" plain icon="el-icon-position" @click="handleBusinessAction('${action.code}')">${action.name}</el-button>
          #end
          #end
        </div>
      </div>

      #if($showQuery)
      <div class="filter-bar">
#foreach ($column in $queryColumns)
#set($renderQueryField = false)
#if($designed)
#set($renderQueryField = true)
#elseif($column.isQuery == "1")
#set($renderQueryField = true)
#end
#if($renderQueryField)
#set($javaField=$column.javaField)
#set($columnComment=$column.columnComment)
#set($remoteSelect=$qingRemoteSelectFields.contains($javaField))
#if($column.htmlType == "input")
        <el-input class="filter-item" placeholder="请输入${columnComment}" clearable v-model="queryParams.${javaField}" @keyup.enter.native="load" />
#elseif($column.htmlType == "select" || $column.htmlType == "radio")
        <el-select class="filter-item" v-model="queryParams.${javaField}" placeholder="请选择${columnComment}" clearable>
#if($remoteSelect)
          <el-option
            v-for="item in getSelectOptions('${javaField}')"
            :key="item.value"
            :label="item.label"
            :value="item.value" />
#else
          <el-option
            v-for="item in _dict.getDictDataByType('${column.dictType}')"
            :key="item.value"
            :label="item.name"
            :value="item.value" />
#end
        </el-select>
#elseif($column.htmlType == "datetime")
        <el-date-picker class="filter-item" v-model="queryParams.${javaField}" type="date" value-format="yyyy-MM-dd" placeholder="选择${columnComment}" />
#end
#end
#end
        <el-button type="primary" icon="el-icon-search" @click="load">搜索</el-button>
        <el-button icon="el-icon-refresh" @click="reset">重置</el-button>
      </div>
      #end

#if($isCardListLayout)
      <div class="resource-card-grid">
        <article v-for="item in ${businessName}List" :key="item.${pkColumn.javaField}" class="resource-card-item">
          #if($showBatchDelete)
          <el-checkbox class="resource-card-check" v-model="item.__checked" @change="handleCardSelectionChange" />
          #end
          <div class="resource-card-body">
#if($cardImageColumn)
            <el-image
              v-if="item.${cardImageColumn.javaField}"
              class="resource-card-image"
              :src="item.${cardImageColumn.javaField}"
              :preview-src-list="[item.${cardImageColumn.javaField}]" />
#end
#if($cardTitleColumn)
            <h3 class="resource-card-title">{{ item.${cardTitleColumn.javaField} || '-' }}</h3>
#end
#foreach ($column in $cardColumns)
#set($renderCardField = false)
#if($designed)
#set($renderCardField = true)
#elseif($column.isList == "1")
#set($renderCardField = true)
#end
#if($renderCardField)
#set($javaField=$column.javaField)
#set($columnComment=$column.columnComment)
#set($remoteSelect=$qingRemoteSelectFields.contains($javaField))
#if($column.htmlType == "imageUpload")
            <el-image
              v-if="item.${javaField}"
              class="resource-card-image"
              :src="item.${javaField}"
              :preview-src-list="[item.${javaField}]" />
#elseif($column.htmlType == "select" || $column.htmlType == "radio")
            <div class="resource-card-field">
              <span>${columnComment}</span>
#if($remoteSelect)
              <strong>{{ getOptionLabel('${javaField}', item.${javaField}) }}</strong>
#else
              <strong>{{ _dict.getDictLabel('${column.dictType}', item.${javaField}) || '-' }}</strong>
#end
            </div>
#else
            <div class="resource-card-field">
              <span>${columnComment}</span>
              <strong>{{ item.${javaField} || '-' }}</strong>
            </div>
#end
#end
#end
          </div>
          #if($showView || $showEdit || $showDelete || $hasRowBusinessActions)
          <div class="resource-card-actions">
            #if($showView)
            <el-button type="text" icon="el-icon-view" @click="handleView(item)">查看</el-button>
            #end
            #if($showEdit)
            <el-button type="text" icon="el-icon-edit" @click="handleEdit(item)">编辑</el-button>
            #end
            #if($showDelete)
            <el-popconfirm
              confirm-button-text="确定"
              cancel-button-text="取消"
              icon="el-icon-info"
              icon-color="red"
              title="确定删除这条数据吗？"
              @confirm="del(item.${pkColumn.javaField})">
              <el-button slot="reference" type="text" icon="el-icon-delete" class="danger-text">删除</el-button>
            </el-popconfirm>
            #end
            #foreach($action in $rowBusinessActions)
            <el-button type="text" icon="el-icon-position" @click="handleBusinessAction('${action.code}', item)">${action.name}</el-button>
            #end
          </div>
          #end
        </article>
      </div>
#else
      <el-table :data="${businessName}List" border stripe class="resource-table" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" />
#if(!$designed)
        <el-table-column prop="${pkColumn.javaField}" label="ID" width="90" />
#end
#foreach ($column in $tableColumns)
#set($renderTableField = false)
#if($designed)
#set($renderTableField = true)
#elseif($column.isList == "1")
#set($renderTableField = true)
#end
#if($renderTableField)
#set($javaField=$column.javaField)
#set($columnComment=$column.columnComment)
#set($remoteSelect=$qingRemoteSelectFields.contains($javaField))
#if($column.htmlType == "datetime")
        <el-table-column prop="${javaField}" label="${columnComment}" align="center" width="180" />
#elseif($column.htmlType == "imageUpload")
        <el-table-column prop="${javaField}" label="${columnComment}" align="center" width="110">
          <template slot-scope="scope">
            <el-image
              v-if="scope.row.${javaField}"
              class="table-image"
              :src="scope.row.${javaField}"
              :preview-src-list="[scope.row.${javaField}]" />
            <span v-else>-</span>
          </template>
        </el-table-column>
#elseif($column.htmlType == "select" || $column.htmlType == "radio")
        <el-table-column prop="${javaField}" label="${columnComment}" align="center">
          <template slot-scope="scope">
#if($remoteSelect)
            {{ getOptionLabel('${javaField}', scope.row.${javaField}) }}
#else
            {{ _dict.getDictLabel('${column.dictType}', scope.row.${javaField}) }}
#end
          </template>
        </el-table-column>
#else
        <el-table-column prop="${javaField}" label="${columnComment}" align="center" />
#end
#end
#end
        #if($showView || $showEdit || $showDelete || $hasRowBusinessActions)
        <el-table-column label="操作" width="230" align="center">
          <template slot-scope="scope">
            #if($showView)
            <el-button type="text" icon="el-icon-view" @click="handleView(scope.row)">查看</el-button>
            #end
            #if($showEdit)
            <el-button type="text" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
            #end
            #if($showDelete)
            <el-popconfirm
              confirm-button-text="确定"
              cancel-button-text="取消"
              icon="el-icon-info"
              icon-color="red"
              title="确定删除这条数据吗？"
              @confirm="del(scope.row.${pkColumn.javaField})">
              <el-button slot="reference" type="text" icon="el-icon-delete" class="danger-text">删除</el-button>
            </el-popconfirm>
            #end
            #foreach($action in $rowBusinessActions)
            <el-button type="text" icon="el-icon-position" @click="handleBusinessAction('${action.code}', scope.row)">${action.name}</el-button>
            #end
          </template>
        </el-table-column>
        #end
      </el-table>
#end

      <el-pagination
        class="pagination"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="queryParams.pageNum"
        :page-sizes="[10, 20, 50, 100]"
        :page-size="queryParams.pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total" />
    </section>

#if($hasPageDesignBottomBusinessBlocks)
    <section class="embedded-business-blocks bottom-business-blocks">
#foreach($block in $bottomBusinessBlocks)
      <${block.componentName} />
#end
    </section>
#end

    #if($renderForm)
    <el-dialog :title="viewing ? '查看${functionName}' : (form.${pkColumn.javaField} ? '编辑${functionName}' : '新增${functionName}')" :visible.sync="dialogFormVisible" width="520px">
      <el-form ref="form" :model="form" label-width="110px" size="small" :disabled="viewing">
#foreach ($column in $formColumns)
#set($renderFormField = false)
#if($designed)
#set($renderFormField = true)
#elseif($column.isEdit == "1")
#set($renderFormField = true)
#end
#if($renderFormField)
#set($javaField=$column.javaField)
#set($columnComment=$column.columnComment)
#set($remoteSelect=$qingRemoteSelectFields.contains($javaField))
        <el-form-item label="${columnComment}" prop="${javaField}"#if($column.isRequired == "1") :rules="[{ required: true, message: '${columnComment}不能为空', trigger: #if($column.htmlType == "select")'change'#else'blur'#end }]"#end>
#if($column.htmlType == "input")
          <el-input v-model="form.${javaField}" placeholder="请输入${columnComment}" />
#elseif($column.htmlType == "textarea")
          <el-input v-model="form.${javaField}" type="textarea" placeholder="请输入${columnComment}" />
#elseif($column.htmlType == "select" || $column.htmlType == "radio")
          <el-select v-model="form.${javaField}" placeholder="请选择${columnComment}" clearable>
#if($remoteSelect)
            <el-option
              v-for="item in getSelectOptions('${javaField}')"
              :key="item.value"
              :label="item.label"
              :value="item.value" />
#else
            <el-option
              v-for="item in _dict.getDictDataByType('${column.dictType}')"
              :key="item.value"
              :label="item.name"
              :value="item.value" />
#end
          </el-select>
#elseif($column.htmlType == "datetime")
          <el-date-picker v-model="form.${javaField}" type="date" value-format="yyyy-MM-dd" placeholder="选择${columnComment}" />
#elseif($column.htmlType == "imageUpload")
          <el-upload
            class="avatar-uploader"
            action="/api/files/upload"
            :show-file-list="false"
            :on-success="(res) => uploadSuccess('${javaField}', res)">
            <img v-if="form.${javaField}" :src="form.${javaField}" class="avatar" />
            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
          </el-upload>
#elseif($column.htmlType == "fileUpload")
          <el-upload
            action="/api/files/upload"
            :on-success="(res) => uploadSuccess('${javaField}', res)">
            <el-button size="small" type="primary">点击上传</el-button>
          </el-upload>
          <div v-if="form.${javaField}" class="file-link">{{ form.${javaField} }}</div>
#end
        </el-form-item>
#end
#end
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button v-if="!viewing" type="primary" @click="save">确定</el-button>
      </div>
    </el-dialog>
    #end
  </section>
</template>

<script>
#foreach($block in $embeddedBusinessBlocks)
import ${block.componentName} from "${block.relativeImportPath}"
#end

export default {
  name: "${BusinessName}",
#if($hasPageDesignEmbeddedBusinessBlocks)
  components: {
#foreach($block in $embeddedBusinessBlocks)
    ${block.componentName}#if($foreach.hasNext),#end
#end
  },
#end
  data() {
    return {
      ${businessName}List: [],
      total: 0,
      queryParams: {
        pageNum: 1,
        pageSize: 10,
#if($currentUserOnly)
        __currentUserOnly: true,
#end
#foreach ($column in $queryColumns)
#set($renderQueryParam = false)
#if(!$showQuery)
#set($renderQueryParam = false)
#elseif($designed)
#set($renderQueryParam = true)
#elseif($column.isQuery == "1")
#set($renderQueryParam = true)
#end
#if($renderQueryParam)
        ${column.javaField}: undefined,
#end
#end
      },
      form: {},
      viewing: false,
      dialogFormVisible: false,
      multipleSelection: [],
      remoteOptionMap: {},
      remoteSelectConfig: {
#foreach($remote in $qingRemoteSelects)
        ${remote.field}: {
          path: "${remote.path}",
          valueField: "${remote.valueField}",
          labelField: "${remote.labelField}"
        }#if($foreach.hasNext),#end
#end
      },
      activeTab: "最新公告",
      noticeTabs: ["最新公告", "热门赛事", "热门攻略", "热门帖子"],
      notices: [
        { title: "《${functionName}》资源内容更新与支持", time: "2025-06-24 16:50:40" },
        { title: "社区活动与资源维护窗口预告", time: "2025-06-24 16:48:30" },
        { title: "新内容发布和玩家反馈整理", time: "2025-06-24 10:30:24" },
        { title: "版本资料、攻略和周边内容同步", time: "2025-06-23 19:20:12" }
      ],
      businessActionMap: {
#foreach($action in $allPageBusinessActions)
        "${action.code}": {
          method: "${action.method}",
          path: "${action.path}",
          requestFields: [#foreach($field in $action.requestFields)"${field}"#if($foreach.count != $action.requestFields.size()), #end#end]
        }#if($foreach.count != $allPageBusinessActions.size()),#end
#end
      }
    }
  },
  created() {
    this.loadRemoteOptions()
    this.load()
  },
  methods: {
    loadRemoteOptions() {
      Object.keys(this.remoteSelectConfig).forEach(field => {
        const config = this.remoteSelectConfig[field]
        this.request.get(config.path, {
          params: { pageNum: 1, pageSize: 999 }
        }).then(res => {
          const data = res.data || {}
          const records = Array.isArray(data) ? data : (data.records || [])
          const options = records.map(item => ({
            value: item[config.valueField],
            label: item[config.labelField]
          }))
          this.#[[$set]]#(this.remoteOptionMap, field, options)
        })
      })
    },
    getSelectOptions(field) {
      return this.remoteOptionMap[field] || []
    },
    getOptionLabel(field, value) {
      const option = this.getSelectOptions(field).find(item => String(item.value) === String(value))
      if (option) {
        return option.label
      }
      return value === undefined || value === null || value === "" ? "-" : value
    },
    load() {
      this.request.get("/${moduleName}/${businessName}/page", {
        params: this.queryParams
      }).then(res => {
        const page = res.data || {}
        this.${businessName}List = page.records || []
        this.total = page.total || 0
      })
    },
    save() {
      this.#[[$refs]]#.form.validate(valid => {
        if (!valid) {
          return
        }
        this.request.post("/${moduleName}/${businessName}", this.form).then(res => {
          if (res.code === "200") {
            this.#[[$message]]#.success("保存成功")
            this.dialogFormVisible = false
            this.load()
          } else {
            this.#[[$message]]#.error(res.msg || "保存失败")
          }
        })
      })
    },
    handleAdd() {
      this.form = {}
      this.viewing = false
      this.dialogFormVisible = true
      this.#[[$nextTick]]#(() => this.#[[$refs]]#.form && this.#[[$refs]]#.form.clearValidate())
    },
    handleView(row) {
      this.form = JSON.parse(JSON.stringify(row))
      this.viewing = true
      this.dialogFormVisible = true
    },
    handleEdit(row) {
      this.form = JSON.parse(JSON.stringify(row))
      this.viewing = false
      this.dialogFormVisible = true
      this.#[[$nextTick]]#(() => this.#[[$refs]]#.form && this.#[[$refs]]#.form.clearValidate())
    },
    del(${pkColumn.javaField}) {
      this.request.delete("/${moduleName}/${businessName}/" + ${pkColumn.javaField}).then(res => {
        if (res.code === "200") {
          this.#[[$message]]#.success("删除成功")
          this.load()
        } else {
          this.#[[$message]]#.error(res.msg || "删除失败")
        }
      })
    },
    handleSelectionChange(val) {
      this.multipleSelection = val
    },
    handleCardSelectionChange() {
      this.multipleSelection = this.${businessName}List.filter(item => item.__checked)
    },
    delBatch() {
      const ids = this.multipleSelection.map(item => item.${pkColumn.javaField})
      if (!ids.length) {
        this.#[[$message]]#.warning("请先选择要删除的数据")
        return
      }
      this.request.post("/${moduleName}/${businessName}/del/batch", ids).then(res => {
        if (res.code === "200") {
          this.#[[$message]]#.success("批量删除成功")
          this.load()
        } else {
          this.#[[$message]]#.error(res.msg || "批量删除失败")
        }
      })
    },
    reset() {
      this.queryParams = {
        pageNum: 1,
        pageSize: 10#if($currentUserOnly),
        __currentUserOnly: true#end
      }
      this.load()
    },
    handleBusinessAction(code, row) {
      const action = this.businessActionMap[code]
      if (!action || !action.path) {
        this.#[[$message]]#.warning("动作未配置")
        return
      }
      const payload = this.buildBusinessActionPayload(action, row)
      const method = String(action.method || "POST").toLowerCase()
      const request = method === "get"
        ? this.request.get(action.path, { params: payload })
        : this.request[method] ? this.request[method](action.path, payload) : this.request.post(action.path, payload)
      request.then(res => {
        if (res.code === "200") {
          this.#[[$message]]#.success("操作成功")
          this.load()
        } else {
          this.#[[$message]]#.error(res.msg || "操作失败")
        }
      })
    },
    buildBusinessActionPayload(action, row) {
      const payload = {}
      ;(action.requestFields || []).forEach(field => {
        const value = this.resolvePayloadValue(field, row)
        if (value !== undefined) {
          payload[field] = value
        }
      })
      return payload
    },
    resolvePayloadValue(field, row) {
      const camelField = this.toCamelCase(field)
      const sources = [row, this.form, this.queryParams]
      for (const source of sources) {
        if (!source) {
          continue
        }
        if (source[field] !== undefined) {
          return source[field]
        }
        if (source[camelField] !== undefined) {
          return source[camelField]
        }
      }
      return undefined
    },
    toCamelCase(value) {
      return String(value || "").replace(/_([a-zA-Z0-9])/g, (_, char) => char.toUpperCase())
    },
    handleSizeChange(pageSize) {
      this.queryParams.pageSize = pageSize
      this.load()
    },
    handleCurrentChange(pageNum) {
      this.queryParams.pageNum = pageNum
      this.load()
    },
    uploadSuccess(field, res) {
      if (res && res.code === "200" && res.data && res.data.url) {
        this.#[[$set]]#(this.form, field, res.data.url)
      } else {
        this.#[[$message]]#.error("上传失败，请重试")
      }
    }
  }
}
</script>

<style scoped>
.portal-page {
  display: grid;
  gap: 22px;
}

.embedded-business-blocks {
  display: grid;
  gap: 16px;
}

.content-board {
  display: grid;
  grid-template-columns: minmax(0, 1.36fr) minmax(320px, 0.64fr);
  gap: 24px;
  align-items: stretch;
}

.feature-card {
  position: relative;
  min-height: 270px;
  overflow: hidden;
  background: #ffffff;
}

.feature-illustration {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(135deg, rgba(10, 66, 99, 0.92), rgba(255, 126, 86, 0.9)),
    #184967;
}

.feature-illustration::before,
.feature-illustration::after {
  position: absolute;
  display: block;
  content: "";
}

.feature-illustration::before {
  left: 8%;
  top: 18%;
  width: 48%;
  height: 42%;
  border: 8px solid rgba(255, 255, 255, 0.8);
  border-radius: 6px;
  transform: rotate(-8deg);
}

.feature-illustration::after {
  right: 9%;
  bottom: -12%;
  width: 290px;
  height: 290px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 36% 38%, #ffffff 0 10px, transparent 11px),
    radial-gradient(circle at 64% 38%, #ffffff 0 10px, transparent 11px),
    radial-gradient(circle at 50% 58%, transparent 0 38px, #153d58 39px 45px, transparent 46px),
    #39a6d8;
  box-shadow: 0 20px 0 #133c58;
}

.device-face {
  position: absolute;
  left: 24%;
  bottom: 20%;
  display: grid;
  grid-template-columns: repeat(2, 36px);
  gap: 18px;
  padding: 18px;
  border-radius: 48px;
  background: rgba(21, 62, 88, 0.9);
  transform: rotate(7deg);
}

.device-face span {
  width: 36px;
  height: 36px;
  border: 5px solid #f7ebe0;
  border-radius: 50%;
}

.feature-copy {
  position: absolute;
  left: 28px;
  bottom: 24px;
  max-width: 420px;
  color: #ffffff;
}

.feature-copy span {
  display: inline-block;
  margin-bottom: 8px;
  color: #ffe1b6;
  font-size: 13px;
  font-weight: 700;
}

.feature-copy h2,
.feature-copy p,
.panel-heading h2 {
  margin: 0;
  letter-spacing: 0;
}

.feature-copy h2 {
  font-size: 28px;
  line-height: 1.25;
}

.feature-copy p {
  margin-top: 8px;
  color: rgba(255, 255, 255, 0.88);
  line-height: 1.7;
}

.notice-panel {
  min-width: 0;
  background: #ffffff;
}

.notice-tabs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  border-bottom: 1px solid #edf0f5;
}

.notice-tabs button {
  position: relative;
  min-height: 38px;
  border: 0;
  color: #475569;
  background: transparent;
  cursor: pointer;
}

.notice-tabs button.active {
  color: #19a6ad;
  font-weight: 700;
}

.notice-tabs button.active::after {
  position: absolute;
  right: 8px;
  bottom: -1px;
  left: 8px;
  height: 2px;
  background: #19a6ad;
  content: "";
}

.notice-list {
  display: grid;
  gap: 18px;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
}

.notice-list li {
  display: grid;
  gap: 7px;
}

.notice-list strong {
  color: #172033;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.55;
}

.notice-list span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: #7b8493;
  font-size: 13px;
}

.data-panel,
.notice-panel {
  padding: 20px;
  border: 1px solid #edf0f5;
  border-radius: 4px;
}

.data-panel {
  background: #ffffff;
}

.split-data-panel {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: 16px;
}

.split-data-panel .panel-heading {
  grid-column: 1 / -1;
  margin-bottom: 0;
}

.split-data-panel .filter-bar {
  align-content: flex-start;
  align-self: start;
  flex-direction: column;
  margin-bottom: 0;
  padding: 14px;
  border: 1px solid #edf0f5;
  border-radius: 4px;
  background: #f8fafc;
}

.split-data-panel .filter-item,
.split-data-panel .filter-bar .el-button {
  width: 100%;
}

.split-data-panel .resource-table,
.split-data-panel .resource-card-grid,
.split-data-panel .pagination {
  grid-column: 2;
}

.panel-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 18px;
}

.section-kicker {
  color: #19a6ad;
  font-size: 13px;
  font-weight: 700;
}

.panel-heading h2 {
  margin-top: 6px;
  color: #172033;
  font-size: 22px;
}

.panel-actions,
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.filter-bar {
  margin-bottom: 14px;
}

.filter-item {
  width: 220px;
}

.resource-table {
  width: 100%;
}

.resource-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px;
}

.resource-card-item {
  position: relative;
  display: grid;
  gap: 12px;
  min-height: 180px;
  padding: 16px;
  border: 1px solid #edf0f5;
  border-radius: 4px;
  background: #ffffff;
}

.resource-card-check {
  position: absolute;
  top: 12px;
  right: 12px;
}

.resource-card-body {
  display: grid;
  gap: 10px;
}

.resource-card-field {
  display: grid;
  gap: 4px;
}

.resource-card-title {
  margin: 0;
  color: #172033;
  font-size: 17px;
  line-height: 1.35;
}

.resource-card-field span {
  color: #7b8493;
  font-size: 12px;
}

.resource-card-field strong {
  color: #172033;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
  word-break: break-word;
}

.resource-card-image {
  width: 100%;
  height: 132px;
  border-radius: 4px;
  object-fit: cover;
}

.resource-card-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding-top: 4px;
  border-top: 1px solid #edf0f5;
}

.pagination {
  margin-top: 14px;
  text-align: right;
}

.danger-text {
  color: #f56c6c;
}

.table-image {
  width: 52px;
  height: 52px;
  border-radius: 4px;
}

.avatar-uploader .avatar {
  display: block;
  width: 96px;
  height: 96px;
  object-fit: cover;
}

.avatar-uploader-icon {
  width: 96px;
  height: 96px;
  border: 1px dashed #d9d9d9;
  border-radius: 4px;
  color: #8c939d;
  line-height: 96px;
  text-align: center;
}

.file-link {
  margin-top: 6px;
  color: #606266;
  word-break: break-all;
}

@media (max-width: 980px) {
  .content-board {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 720px) {
  .split-data-panel {
    grid-template-columns: 1fr;
  }

  .split-data-panel .panel-heading,
  .split-data-panel .resource-table,
  .split-data-panel .resource-card-grid,
  .split-data-panel .pagination {
    grid-column: 1;
  }

  .panel-heading {
    align-items: flex-start;
    flex-direction: column;
  }

  .filter-item {
    width: 100%;
  }

  .notice-tabs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
</style>
