zhuli 1 місяць тому
батько
коміт
7351f982fa

+ 23 - 0
src/api/modules/homeEntry.ts

@@ -0,0 +1,23 @@
+import { ResPage, StoreUser } from "@/api/interface/index";
+import { PORT_NONE } from "@/api/config/servicePort";
+import http from "@/api";
+
+//个人实名
+export const verifyIdInfo = params => {
+  return http.get<StoreUser.ResStoreUserList>(PORT_NONE + `/merchantAuth/verifyIdInfo`, params);
+};
+
+//信息提交
+export const applyStore = params => {
+  return http.post(PORT_NONE + `/storeManage/applyStore`, params);
+};
+
+//用户信息
+export const getMerchantByPhone = params => {
+  return http.get<StoreUser.ResStoreUserList>(PORT_NONE + `/merchantUser/getMerchantByPhone`, params);
+};
+
+//通知列表
+export const getNoticeList = params => {
+  return http.get<StoreUser.ResStoreUserList>(PORT_NONE + `/notice/getNoticeList`, params);
+};

+ 24 - 0
src/api/modules/newLoginApi.ts

@@ -1,5 +1,6 @@
 import type { Login } from "@/api/interface";
 import httpLogin from "@/api/indexApi";
+import { Upload } from "@/api/interface/index";
 // 获取图片验证码
 export const getImgCode = () => {
   return httpLogin.get(
@@ -31,3 +32,26 @@ export const loginAccount = params => {
 export const forgetPassword = params => {
   return httpLogin.get(`/alienStorePlatform/storePlatformLogin/updatePassword`, params, { loading: false });
 };
+
+//经营板块
+export const getBusinessSection = () => {
+  return httpLogin.get(`/alienStore/store/info/getBusinessSection`);
+};
+
+//经营种类
+export const getBusinessSectionTypes = (params: { parentId: string }) => {
+  return httpLogin.get(`/alienStore/store/info/getBusinessSectionTypes`, params);
+};
+//经纬度查询
+export const getInputPrompt = params => {
+  return httpLogin.get(`/alienStore/gaode/getInputPrompt`, params);
+};
+
+//所在地区
+export const getDistrict = params => {
+  return httpLogin.get(`/alienStore/gaode/getDistrict`, params);
+};
+//文件上传
+export const uploadImg = (params: FormData) => {
+  return httpLogin.post<Upload.ResFileUrl>(`/alienStore/file/uploadMore`, params, { cancel: false });
+};

+ 15 - 1
src/assets/json/authMenuList.json

@@ -16,6 +16,20 @@
       }
     },
     {
+      "path": "/home/notice",
+      "name": "notice",
+      "component": "/home/notice",
+      "meta": {
+        "icon": "List",
+        "title": "系统通知",
+        "isLink": "",
+        "isHide": true,
+        "isFull": false,
+        "isAffix": false,
+        "isKeepAlive": false
+      }
+    },
+    {
       "path": "/groupPackageManagement",
       "name": "groupPackageManagementIndex",
       "component": "/groupPackageManagement/index",
@@ -376,7 +390,7 @@
           "component": "/financialManagement/index",
           "meta": {
             "icon": "CreditCard",
-            "title": "财务管理",
+            "title": "账户总览",
             "isLink": "",
             "isHide": false,
             "isFull": false,

+ 4 - 1
src/layouts/components/Header/components/InfoDialog.vue

@@ -37,9 +37,12 @@
 import { ref, reactive } from "vue";
 import { ElMessage, type FormInstance, type FormRules } from "element-plus";
 import { Plus } from "@element-plus/icons-vue";
+import { getMerchantByPhone } from "@/api/modules/homeEntry.ts";
 
 const dialogVisible = ref(false);
-const openDialog = () => {
+const openDialog = async () => {
+  const res = await getMerchantByPhone({ phone: "15242687180" });
+  console.log(res);
   dialogVisible.value = true;
 };
 

+ 184 - 180
src/views/financialManagement/index.vue

@@ -1,203 +1,207 @@
 <template>
-  <div class="table-box">
-    <ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" :data-callback="dataCallback">
-      <!-- 表格 header 按钮 -->
-      <template #tableHeader="scope">
-        <el-button type="primary" :icon="Download" @click="exportInfoExcel(scope)"> 导出 </el-button>
-      </template>
-      <template #expand="scope">
-        {{ scope.row }}
-      </template>
-      <!-- 表格操作 -->
-      <template #operation="scope">
-        <!-- 审批通过和拒绝按钮仅在状态为0时显示 -->
-        <template v-if="scope.row.status === '0'">
-          <el-button type="primary" link @click="changeTypes(scope.row, 'pass')"> 审核通过 </el-button>
-          <el-button type="primary" link @click="changeTypes(scope.row, '')"> 审核拒绝 </el-button>
-        </template>
-        <el-button type="primary" link @click="toDetail(scope.row)"> 查看详情 </el-button>
-      </template>
-    </ProTable>
-
-    <el-dialog v-model="dialogFormVisible" title="审核拒绝" width="500">
-      <el-form :model="form">
-        <el-form-item label="" label-width="0">
-          <el-input v-model="form.comment" autocomplete="off" type="textarea" maxlength="200" />
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <div class="dialog-footer">
-          <el-button @click="closeDialog"> 取消 </el-button>
-          <el-button type="primary" @click="handleSubmit"> 驳回 </el-button>
+  <div class="financial-dashboard">
+    <h3 class="title"><el-image :src="homeIcon" class="homeIcon" />账户总览</h3>
+    <el-row :gutter="16">
+      <el-col v-for="card in cards" :key="card.key" :span="5">
+        <div class="summary-card" :class="{ 'is-disabled': card.disabled }">
+          <div class="card-header">
+            <div class="header-left">
+              <span class="card-title">{{ card.title }}</span>
+              <el-tooltip v-if="card.tooltip" :content="card.tooltip" placement="top">
+                <el-icon class="info-icon">
+                  <QuestionFilled />
+                </el-icon>
+              </el-tooltip>
+            </div>
+            <el-icon v-if="card.showArrow" class="arrow-icon" @click="handleAction(card)">
+              <ArrowRight />
+            </el-icon>
+          </div>
+          <div class="card-amount">¥{{ formatAmount(card.amount) }}</div>
+          <div class="card-button-wrapper">
+            <el-button
+              v-if="card.buttonText"
+              class="card-button"
+              size="large"
+              :type="card.disabled ? 'default' : 'primary'"
+              :plain="card.disabled"
+              :disabled="card.disabled"
+              @click="handleAction(card)"
+            >
+              {{ card.buttonText }}
+            </el-button>
+          </div>
         </div>
-      </template>
-    </el-dialog>
+      </el-col>
+    </el-row>
   </div>
 </template>
 
-<script setup lang="tsx" name="financialManagement">
-import { ref, reactive, onMounted, onActivated } from "vue";
-import { useRouter } from "vue-router";
-import { ElMessage } from "element-plus";
-import ProTable from "@/components/ProTable/index.vue";
-import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
-import { Download } from "@element-plus/icons-vue";
-import { audit, exportExcelStaffConfig, getStaffConfigList } from "@/api/modules/staffConfig";
-
-const router = useRouter();
-const dialogFormVisible = ref(false);
-const form = reactive({
-  comment: ""
-});
-
-const rowData = ref<any>();
-
-const statusEnum = [
-  { value: "0", label: "待审核" },
-  { value: "1", label: "审核通过" },
-  { value: "2", label: "审核拒绝" }
-];
-// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
-const initParam = reactive({});
-
-// 定义 filterValues
-const filterValues = reactive({});
-
-const getStatusObj = (statusValue: string) => {
-  const statusObj = statusEnum.find(item => item.value === statusValue);
-  if (statusObj) {
-    filterValues.status = statusObj;
-  } else {
-    filterValues.status = "";
-  }
-  return statusObj;
-};
-
-// ProTable 实例
-const proTable = ref<ProTableInstance>();
-
-// 页面加载时触发查询
-onMounted(() => {
-  proTable.value?.getTableList();
-});
-
-// 从其他页面返回时触发查询
-onActivated(() => {
-  proTable.value?.getTableList();
-});
+<script setup lang="ts" name="financialManagement">
+import homeIcon from "../../assets/images/home-icon.png";
 
-// dataCallback 是对于返回的表格数据做处理,如果你后台返回的数据不是 list && total 这些字段,可以在这里进行处理成这些字段
-// 或者直接去 hooks/useTable.ts 文件中把字段改为你后端对应的就行
-const dataCallback = (data: any) => {
-  return {
-    list: data.records,
-    total: data.total
-  };
-};
-
-// 如果你想在请求之前对当前请求参数做一些操作,可以自定义如下函数:params 为当前所有的请求参数(包括分页),最后返回请求列表接口
-// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
-const getTableList = (params: any) => {
-  let newParams = JSON.parse(JSON.stringify(params));
-  return getStaffConfigList(newParams);
+import { computed } from "vue";
+import { useRouter } from "vue-router";
+import { ArrowRight, QuestionFilled } from "@element-plus/icons-vue";
+
+type FinancialCard = {
+  key: string;
+  title: string;
+  amount: number;
+  tooltip?: string;
+  buttonText?: string;
+  disabled?: boolean;
+  showArrow?: boolean;
+  route?: string;
+  action?: () => void;
 };
 
-// 跳转详情页
-const toDetail = row => {
-  router.push(`/store/financialManagementDetail?id=${row.id}`);
-};
+const router = useRouter();
 
-// 表格配置项
-const columns = reactive<ColumnProps<any>[]>([
-  { type: "index", fixed: "left", label: "序号", width: 130 },
-  { prop: "storeName", label: "所属店铺" },
-  { prop: "name", label: "名称" },
-  { prop: "description", label: "描述" },
+const cards = computed<FinancialCard[]>(() => [
+  {
+    key: "todayIncome",
+    title: "今日收益",
+    amount: 0,
+    tooltip: "今日收益=今日已核销到账金额-技术服务费",
+    showArrow: true,
+    route: "/financialManagement/detail"
+  },
   {
-    prop: "status",
-    label: "状态",
-    render: scope => {
-      const statusObj = getStatusObj(scope.row.status);
-      return statusObj ? statusObj.label : "未知状态";
-    },
-    search: {
-      el: "select"
-    },
-    enum: statusEnum,
-    fieldNames: { label: "label", value: "value" }
+    key: "withdrawable",
+    title: "可提现金额",
+    amount: 0,
+    tooltip: "收益产生后3天可提现,28天自动",
+    buttonText: "提现",
+    disabled: true
   },
-  { prop: "operation", label: "操作", fixed: "right", width: 330 }
+  {
+    key: "arrivedAmount",
+    title: "已到账期金额",
+    amount: 0,
+    tooltip: "已完成入账的金额总计",
+    buttonText: "查看",
+    route: "/financialManagement/detail"
+  },
+  {
+    key: "pendingAmount",
+    title: "未到账期金额",
+    amount: 0,
+    tooltip: "正在处理中的预计入账金额",
+    buttonText: "查看",
+    route: "/financialManagement/detail"
+  }
 ]);
 
-const changeTypes = (row: any, status: string) => {
-  rowData.value = row;
-  if (status === "pass") {
-    handleChangeStatus(row, "1");
-  } else {
-    form.comment = "";
-    dialogFormVisible.value = true;
+const handleAction = (card: FinancialCard) => {
+  if (card.disabled) return;
+  if (card.action) {
+    card.action();
+    return;
+  }
+  if (card.route) {
+    router.push(card.route);
   }
 };
 
-const handleChangeStatus = async (row: any, status: string) => {
-  try {
-    let res = await audit({ id: row.id, status: status, rejectionReason: form.comment });
-    if (res.code === 200) {
-      proTable.value?.getTableList();
-      if (status === "2") closeDialog();
-      ElMessage.success("审核成功");
-    }
-  } catch (error) {
-    ElMessage.error("操作失败");
-  }
+const formatAmount = (value: number) => {
+  return value.toLocaleString("zh-CN", { minimumFractionDigits: 0, maximumFractionDigits: 2 });
 };
+</script>
 
-// 导出信息
-const exportInfoExcel = async scope => {
-  let res;
-  // 获取原始状态值(可能为数字、字符串或 undefined)
-  const rawStatus = proTable.value.searchParam.status;
-  // 转换为字符串(处理 undefined/null 为 "" 或保留原始字符串)
-  const statusParam = rawStatus !== undefined && rawStatus !== null ? String(rawStatus) : undefined;
-  // 将筛选条件作为参数传递给后台
-  res = await exportExcelStaffConfig({ status: statusParam });
-  if (res.code === 200) {
-    if (!res.data) {
-      ElMessage.error("暂无可下载数据");
-      return;
+<style scoped lang="scss">
+.financial-dashboard {
+  box-sizing: border-box;
+  width: 100%;
+  height: calc(100vh - 105px);
+  overflow: hidden;
+  background: url("../../assets/images/home-bg.png") center center no-repeat;
+  background-size: cover;
+  .title {
+    display: flex;
+    align-items: center;
+    height: 105px;
+    font-size: 20px;
+    font-weight: 600;
+    color: #ffffff;
+    background: linear-gradient(90deg, #6c8ff8 0%, rgb(255 255 255 / 0%) 100%);
+    .homeIcon {
+      width: 76px;
+      height: 76px;
+      margin-right: 8px;
+      margin-left: 25px;
     }
-    const exportFile = document.createElement("a");
-    exportFile.style.display = "none";
-    exportFile.download = `财务管理.xlsx`;
-    exportFile.href = `${res.data}?timestamp=${new Date().getTime()}`; // 添加时间戳防止缓存
-    document.body.appendChild(exportFile);
-    exportFile.click();
-    document.body.removeChild(exportFile);
-    ElMessage.success("下载成功");
-  }
-};
 
-// 弹窗提交
-const handleSubmit = () => {
-  if (!form.comment) {
-    ElMessage.error("请输入审批意见");
-    return;
+    border-radius: 10px;
+  }
+  :deep(.el-row) {
+    display: flex;
+    margin: 0 !important;
+  }
+  :deep(.el-col) {
+    display: flex;
+  }
+}
+.summary-card {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+  justify-content: space-between;
+  height: 100%;
+  min-height: 148px;
+  padding: 20px 90px;
+  background-color: #ffffff;
+  border: 1px solid #e5e6eb;
+  border-radius: 8px;
+  transition: box-shadow 0.2s;
+  &:hover {
+    box-shadow: 0 6px 12px rgb(31 41 55 / 10%);
+  }
+  &.is-disabled {
+    .card-button {
+      cursor: not-allowed;
+    }
+  }
+}
+.card-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  .header-left {
+    display: inline-flex;
+    gap: 6px;
+    align-items: center;
+  }
+}
+.card-title {
+  font-size: 16px;
+  font-weight: 500;
+  color: #1d2129;
+}
+.card-amount {
+  font-size: 28px;
+  font-weight: 600;
+  line-height: 1.2;
+  color: #1d2129;
+}
+.card-button-wrapper {
+  display: flex;
+  align-items: flex-end;
+  min-height: 40px;
+}
+.card-button {
+  width: 100%;
+}
+.info-icon {
+  font-size: 16px;
+  color: #86909c;
+}
+.arrow-icon {
+  font-size: 18px;
+  color: #c9ccd3;
+  cursor: pointer;
+  &:hover {
+    color: #165dff;
   }
-  handleChangeStatus(rowData.value, "2");
-};
-// 关闭弹窗;
-const closeDialog = () => {
-  dialogFormVisible.value = false;
-  form.comment = "";
-};
-</script>
-
-<style lang="scss" scoped>
-// 在组件样式中添加
-.date-range {
-  display: block; // 确保换行生效
-  padding: 0 8px; // 可选:增加内边距
-  word-wrap: break-word; // 长单词内换行
-  white-space: normal; // 允许自然换行
 }
 </style>

+ 29 - 35
src/views/home/components/go-enter.vue

@@ -4,48 +4,18 @@
     <h3 class="title"><el-image :src="homeIcon" class="homeIcon" />免费入驻店铺</h3>
     <div class="steps-container">
       <el-steps align-center>
-        <el-step>
+        <el-step v-for="(item, index) in entryList" :key="index">
           <template #title>
             <div class="step-title-wrapper">
-              <span class="step-title">个人实名</span>
-              <span class="step-time">约3分钟</span>
+              <span class="step-title">{{ item.title }}</span>
+              <span class="step-time">{{ item.time }}</span>
             </div>
           </template>
           <template #description>
-            <div class="step-desc">填写店铺经营者姓名、身份证号等</div>
-          </template>
-        </el-step>
-        <el-step>
-          <template #title>
-            <div class="step-title-wrapper">
-              <span class="step-title">填写信息</span>
-              <span class="step-time">约30分钟</span>
+            <div class="step-desc">
+              {{ item.desc }}
             </div>
           </template>
-          <template #description>
-            <div class="step-desc">上传营业执照及填写店铺信息等</div>
-          </template>
-        </el-step>
-        <el-step>
-          <template #title>
-            <div class="step-title-wrapper">
-              <span class="step-title">等待审核</span>
-              <span class="step-time">约1-3个工作日</span>
-            </div>
-          </template>
-          <template #description>
-            <div class="step-desc">平台进行资质审核</div>
-          </template>
-        </el-step>
-        <el-step>
-          <template #title>
-            <div class="step-title-wrapper">
-              <span class="step-title">入驻成功</span>
-            </div>
-          </template>
-          <template #description>
-            <div class="step-desc">入驻成功后即可管理您的店铺</div>
-          </template>
         </el-step>
       </el-steps>
     </div>
@@ -55,7 +25,31 @@
   </div>
 </template>
 <script setup lang="ts">
+import { ref, defineProps, defineEmits } from "vue";
 import homeIcon from "../../../assets/images/home-icon.png";
+
+const entryList = ref([
+  {
+    title: "个人实名",
+    time: "约3分钟",
+    desc: "填写店铺经营者姓名、身份证号等"
+  },
+  {
+    title: "填写信息",
+    time: "约30分钟",
+    desc: "上传营业执照及填写店铺信息等"
+  },
+  {
+    title: "等待审核",
+    time: "约1-3个工作日",
+    desc: "平台进行资质审核"
+  },
+  {
+    title: "入驻成功",
+    desc: "入驻成功后即可管理您的店铺"
+  }
+]);
+
 const props = defineProps({
   currentStep: {
     type: Number,

+ 205 - 106
src/views/home/components/go-flow.vue

@@ -5,34 +5,10 @@
       <el-button class="back-btn" @click="handleBack"> 返回 </el-button>
       <div class="progress-container">
         <el-steps :active="currentStep" style="max-width: 1500px" align-center>
-          <el-step>
+          <el-step v-for="(item, index) in entryList" :key="index">
             <template #title>
               <div class="step-title-wrapper">
-                <span class="step-title">个人实名</span>
-                <span class="step-time">约3分钟</span>
-              </div>
-            </template>
-          </el-step>
-          <el-step>
-            <template #title>
-              <div class="step-title-wrapper">
-                <span class="step-title">填写信息</span>
-                <span class="step-time">约30分钟</span>
-              </div>
-            </template>
-          </el-step>
-          <el-step>
-            <template #title>
-              <div class="step-title-wrapper">
-                <span class="step-title">等待审核</span>
-                <span class="step-time">约1-3个工作日</span>
-              </div>
-            </template>
-          </el-step>
-          <el-step>
-            <template #title>
-              <div class="step-title-wrapper">
-                <span class="step-title">入驻成功</span>
+                <span class="step-title">{{ item.title }}</span>
               </div>
             </template>
           </el-step>
@@ -70,94 +46,93 @@
                 <el-input v-model="step2Form.storeName" placeholder="请输入店铺名称" />
               </el-form-item>
 
-              <el-form-item label="容纳人数" prop="capacity">
-                <el-input-number v-model="step2Form.capacity" :min="1" :max="9999" />
+              <el-form-item label="容纳人数" prop="storeCapacity">
+                <el-input-number v-model="step2Form.storeCapacity" :min="1" :max="9999" />
               </el-form-item>
 
               <el-form-item label="门店面积" prop="storeArea">
                 <el-radio-group v-model="step2Form.storeArea">
-                  <el-radio label="小于20平米"> 小于20平米 </el-radio>
-                  <el-radio label="20-50平米"> 20-50平米 </el-radio>
-                  <el-radio label="50-100平米"> 50-100平米 </el-radio>
-                  <el-radio label="100-300平米"> 100-300平米 </el-radio>
-                  <el-radio label="300-500平米"> 300-500平米 </el-radio>
-                  <el-radio label="500-1000平米"> 500-1000平米 </el-radio>
-                  <el-radio label="大于1000平米"> 大于1000平米 </el-radio>
+                  <el-radio label="小于20平米" value="1"> 小于20平米 </el-radio>
+                  <el-radio label="20-50平米" value="2"> 20-50平米 </el-radio>
+                  <el-radio label="50-100平米" value="3"> 50-100平米 </el-radio>
+                  <el-radio label="100-300平米" value="4"> 100-300平米 </el-radio>
+                  <el-radio label="500-1000平米" value="5"> 500-1000平米 </el-radio>
+                  <el-radio label="大于1000平米" value="6"> 大于1000平米 </el-radio>
                 </el-radio-group>
               </el-form-item>
 
-              <el-form-item label="所在地区" prop="location">
-                <el-select v-model="step2Form.province" placeholder="请选择" style="width: 150px; margin-right: 10px">
-                  <el-option label="省份" value="province" />
-                </el-select>
-                <el-select v-model="step2Form.city" placeholder="请选择" style="width: 150px; margin-right: 10px">
-                  <el-option label="城市" value="city" />
-                </el-select>
-                <el-select v-model="step2Form.district" placeholder="请选择" style="width: 150px">
-                  <el-option label="区县" value="district" />
-                </el-select>
+              <el-form-item label="所在地区" prop="region">
+                <el-cascader :props="areaProps" v-model="step2Form.region" style="width: 100%" />
               </el-form-item>
 
-              <el-form-item label="详细地址" prop="detailedAddress">
-                <el-input v-model="step2Form.detailedAddress" type="textarea" :rows="3" placeholder="请输入" />
+              <el-form-item label="详细地址" prop="storeAddress">
+                <el-input v-model="step2Form.storeAddress" type="textarea" :rows="3" placeholder="请输入" />
               </el-form-item>
 
-              <el-form-item label="门店简介" prop="storeIntro">
-                <el-input v-model="step2Form.storeIntro" type="textarea" :rows="3" placeholder="请输入" />
+              <el-form-item label="门店简介" prop="storeBlurb">
+                <el-input v-model="step2Form.storeBlurb" type="textarea" :rows="3" placeholder="请输入" />
               </el-form-item>
 
               <el-form-item label="经营板块" prop="businessSector">
-                <el-radio-group v-model="step2Form.businessSector">
-                  <el-radio label="美食"> 美食 </el-radio>
-                  <el-radio label="酒店/民宿"> 酒店/民宿 </el-radio>
-                  <el-radio label="KTV"> KTV </el-radio>
-                  <el-radio label="洗浴汗蒸"> 洗浴汗蒸 </el-radio>
-                  <el-radio label="按摩足疗"> 按摩足疗 </el-radio>
-                  <el-radio label="丽人美发"> 丽人美发 </el-radio>
-                  <el-radio label="运动健身"> 运动健身 </el-radio>
-                  <el-radio label="医美医疗"> 医美医疗 </el-radio>
+                <el-radio-group v-model="step2Form.businessSector" @change="changeBusinessSector">
+                  <el-radio
+                    v-for="businessSection in businessSectionList"
+                    :value="businessSection.value"
+                    :key="businessSection.value"
+                  >
+                    {{ businessSection.label }}
+                  </el-radio>
                 </el-radio-group>
               </el-form-item>
 
               <el-form-item label="经营种类" prop="businessType">
                 <el-checkbox-group v-model="step2Form.businessType">
-                  <el-checkbox label="小吃快餐"> 小吃快餐 </el-checkbox>
-                  <el-checkbox label="鱼鲜海鲜"> 鱼鲜海鲜 </el-checkbox>
-                  <el-checkbox label="烧烤烤串"> 烧烤烤串 </el-checkbox>
-                  <el-checkbox label="自助餐"> 自助餐 </el-checkbox>
-                  <el-checkbox label="面包蛋糕甜品"> 面包蛋糕甜品 </el-checkbox>
-                  <el-checkbox label="火锅"> 火锅 </el-checkbox>
-                  <el-checkbox label="水果生鲜"> 水果生鲜 </el-checkbox>
-                  <el-checkbox label="特色菜"> 特色菜 </el-checkbox>
-                  <el-checkbox label="中餐"> 中餐 </el-checkbox>
-                  <el-checkbox label="西餐"> 西餐 </el-checkbox>
-                  <el-checkbox label="烤肉"> 烤肉 </el-checkbox>
-                  <el-checkbox label="韩式料理"> 韩式料理 </el-checkbox>
-                  <el-checkbox label="地方菜系"> 地方菜系 </el-checkbox>
-                  <el-checkbox label="日式料理"> 日式料理 </el-checkbox>
-                  <el-checkbox label="轻食"> 轻食 </el-checkbox>
+                  <el-checkbox
+                    v-for="businessType in businessTypeList"
+                    :key="businessType"
+                    :label="businessType.label"
+                    :value="businessType.value"
+                  />
                 </el-checkbox-group>
               </el-form-item>
             </div>
 
             <!-- 右列 -->
             <div class="form-col">
-              <el-form-item label="门店营业状态" prop="businessStatus">
-                <el-radio-group v-model="step2Form.businessStatus">
+              <el-form-item label="门店营业状态" prop="businessType">
+                <el-radio-group v-model="step2Form.businessType">
                   <el-radio label="正常营业"> 正常营业 </el-radio>
                   <el-radio label="暂停营业"> 暂停营业 </el-radio>
                   <el-radio label="筹建中"> 筹建中 </el-radio>
                 </el-radio-group>
               </el-form-item>
-
-              <el-form-item label="经纬度查询" prop="coordinates">
-                <el-input v-model="step2Form.coordinates" placeholder="请输入经纬度" />
+              <el-form-item label="经度" prop="storePositionLongitude">
+                <el-input disabled v-model="step2Form.storePositionLongitude" placeholder="请填写经度" clearable />
+              </el-form-item>
+              <el-form-item label="纬度" prop="storePositionLatitude">
+                <el-input disabled v-model="step2Form.storePositionLatitude" placeholder="请填写纬度" clearable />
+              </el-form-item>
+              <el-form-item label="经纬度查询" prop="addressName">
+                <el-select
+                  v-model="step2Form.addressName"
+                  filterable
+                  placeholder="请输入地址进行查询"
+                  remote
+                  reserve-keyword
+                  :remote-method="getLonAndLat"
+                  @change="selectAddress"
+                >
+                  <el-option v-for="item in addressList" :key="item.id" :label="item.name" :value="item.location">
+                    <span style="float: left">{{ item.name }}</span>
+                    <span style="float: right; font-size: 13px; color: var(--el-text-color-secondary)">{{ item.district }}</span>
+                  </el-option>
+                </el-select>
               </el-form-item>
 
-              <el-form-item label="营业执照" prop="businessLicense">
+              <el-form-item label="营业执照" prop="businessLicenseFiles">
                 <el-upload
                   v-model:file-list="step2Form.businessLicenseFiles"
-                  action="#"
+                  :http-request="handleHttpUpload"
                   list-type="picture-card"
                   :limit="1"
                   :on-exceed="handleExceed"
@@ -169,10 +144,10 @@
                 </el-upload>
               </el-form-item>
 
-              <el-form-item label="合同图片" prop="contractImages">
+              <el-form-item label="合同图片" prop="contractImageFiles">
                 <el-upload
                   v-model:file-list="step2Form.contractImageFiles"
-                  action="#"
+                  :http-request="handleHttpUpload"
                   list-type="picture-card"
                   :limit="20"
                   :on-exceed="handleExceed"
@@ -184,10 +159,10 @@
                 </el-upload>
               </el-form-item>
 
-              <el-form-item label="食品经营许可证" prop="foodLicense">
+              <el-form-item label="食品经营许可证" prop="foodLicenseFiles ">
                 <el-upload
                   v-model:file-list="step2Form.foodLicenseFiles"
-                  action="#"
+                  :http-request="handleHttpUpload"
                   list-type="picture-card"
                   :limit="1"
                   :on-exceed="handleExceed"
@@ -218,10 +193,40 @@
   </div>
 </template>
 <script setup lang="ts">
-import { ref, reactive, watch } from "vue";
-import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from "element-plus";
+import { ref, reactive, watch, onMounted } from "vue";
+import { ElMessage, ElMessageBox, type FormInstance, type FormRules, UploadProps, UploadRequestOptions } from "element-plus";
 import { Plus } from "@element-plus/icons-vue";
 
+import { verifyIdInfo, applyStore } from "@/api/modules/homeEntry.ts";
+import {
+  getBusinessSection,
+  getBusinessSectionTypes,
+  getInputPrompt,
+  getDistrict,
+  uploadImg
+} from "@/api/modules/newLoginApi.ts";
+import { add } from "lodash";
+
+const entryList = ref([
+  {
+    title: "个人实名"
+  },
+  {
+    title: "填写信息"
+  },
+  {
+    title: "等待审核"
+  },
+  {
+    title: "入驻成功"
+  }
+]);
+
+//地址集合
+const addressList = ref<any[]>([]);
+//查询地址名称
+const queryAddress = ref<string>("");
+
 const props = defineProps({
   currentStep: {
     type: Number,
@@ -267,18 +272,21 @@ const step1Rules: FormRules = {
 // 第二步表单
 const step2FormRef = ref<FormInstance>();
 const step2Form = reactive({
+  region: [],
+  addressName: "",
+  storePositionLongitude: "",
+  storePositionLatitude: "",
   storeName: "",
-  capacity: 1,
+  storeCapacity: 1,
   storePhone: "",
   storeArea: "小于20平米",
   province: "",
   city: "",
   district: "",
-  detailedAddress: "",
-  storeIntro: "",
-  businessSector: "美食",
-  businessType: ["小吃快餐", "火锅"],
-  businessStatus: "正常营业",
+  storeAddress: "",
+  storeBlurb: "",
+  businessSector: "1",
+  businessType: "正常营业",
   coordinates: "",
   businessLicenseFiles: [],
   contractImageFiles: [],
@@ -308,14 +316,113 @@ const handleBack = () => {
     setStep(2);
   }
 };
+// 地区选择
+const areaProps: any = {
+  lazy: true,
+  async lazyLoad(node, resolve) {
+    const { level } = node;
+    try {
+      let param = { adCode: node.data.adCode ? node.data.adCode : "" };
+      // 调用后台接口获取数据
+      const response: any = await getDistrict(param as any);
+      // 转换数据格式
+      const nodes = (response?.data?.districts?.[0]?.districts || []).map((item: any) => ({
+        value: item.adcode,
+        adCode: item.adcode,
+        label: item.name,
+        leaf: level >= 2 // 假设最多三级,可以根据实际需求调整
+      }));
 
+      // 返回数据
+      resolve(nodes);
+    } catch (error) {
+      console.error("获取区域数据失败:", error);
+      resolve([]);
+    }
+  }
+};
+//经营板块
+const businessSectionList = ref<any[]>([]);
+const getBusinessSectionList = async () => {
+  let res: any = await getBusinessSection();
+  let addData: any[] = [];
+  (res?.data || []).forEach((element: any) => {
+    addData.push({ value: element.dictId, label: element.dictDetail, parentId: element.parentId });
+  });
+  businessSectionList.value = addData;
+};
+const changeBusinessSector = async (val: any) => {
+  getBusinessTypes(val);
+};
+
+//经营种类
+const businessTypeList = ref<any[]>([]);
+const getBusinessTypes = async (val: any) => {
+  let res: any = await getBusinessSectionTypes({ parentId: val ? val : step2Form.businessSector });
+  let addData1: any[] = [];
+  (res?.data || []).forEach((element: any) => {
+    addData1.push({ value: element.dictId, label: element.dictDetail });
+  });
+  businessTypeList.value = addData1;
+};
+
+// 经纬度查询
+const getLonAndLat = async (keyword: string) => {
+  if (keyword) {
+    console.log("地址查询", keyword);
+    let param = {
+      addressName: keyword
+    };
+    let res: any = await getInputPrompt(param as any);
+    if (res.code == "200") {
+      addressList.value = res?.data?.tips || [];
+      console.log("res", res);
+    } else {
+      ElMessage.error("新增失败!");
+    }
+  } else {
+    addressList.value = [];
+  }
+};
+const selectAddress = async (param: any) => {
+  let locationList = step2Form.addressName.split(",");
+  addressList.value.forEach((item: any) => {
+    if (item.location == step2Form.addressName) {
+      queryAddress.value = item.name;
+    }
+  });
+  step2Form.storePositionLongitude = locationList[0];
+  step2Form.storePositionLatitude = locationList[1];
+};
+//文件上传
+const handleHttpUpload = async (options: UploadRequestOptions) => {
+  let formData = new FormData();
+  formData.append("file", options.file);
+  try {
+    const res: any = await uploadImg(formData);
+    console.log(res);
+  } catch (error) {
+    options.onError(error as any);
+  }
+};
 // 下一步
 const handleNextStep = async () => {
   if (!step1FormRef.value) return;
 
-  await step1FormRef.value.validate(valid => {
+  await step1FormRef.value.validate(async valid => {
     if (valid) {
-      setStep(2);
+      const params = {
+        name: step1Form.name,
+        idCard: step1Form.idNumber,
+        appType: 1
+      };
+      const res = await verifyIdInfo(params);
+      if (res.code == "200") {
+        ElMessage.success(res.msg);
+        setStep(2);
+        getBusinessSectionList();
+        getBusinessTypes();
+      }
     } else {
       ElMessage.error("请完善表单信息");
     }
@@ -329,7 +436,9 @@ const handlePrevStep = () => {
 
 // 提交
 const handleSubmit = async () => {
-  setStep(3);
+  console.log(step2Form);
+  return;
+  let res = await applyStore(param);
   return;
   if (!step2FormRef.value) return;
 
@@ -373,7 +482,6 @@ const handleExceed = () => {
     border-color: #dcdfe6;
   }
   .progress-container {
-    padding: 0 100px;
     margin-bottom: 40px;
     :deep(.el-step__head.is-process .el-step__icon) {
       color: #909399;
@@ -399,15 +507,6 @@ const handleExceed = () => {
             font-weight: 600;
             color: #6c8ff8;
           }
-          .step-time {
-            display: inline-block;
-            padding: 4px 12px;
-            font-size: 12px;
-            color: #6c8ff8;
-            white-space: nowrap;
-            background: #eef1ff;
-            border-radius: 12px;
-          }
         }
       }
     }
@@ -416,7 +515,7 @@ const handleExceed = () => {
     max-width: 800px;
     margin: 0 auto;
     &.step2-form {
-      max-width: 1400px;
+      max-width: 100%;
       .form-row {
         display: flex;
         gap: 40px;

+ 14 - 18
src/views/home/notice.vue

@@ -2,8 +2,7 @@
   <div class="notice-page">
     <!-- 头部 -->
     <div class="header">
-      <h1 class="title">通知</h1>
-      <el-button class="mark-all-read-btn" @click="handleMarkAllRead">
+      <el-button class="mark-all-read-btn" v-if="noticeList.length != 0" @click="handleMarkAllRead">
         <el-icon><CircleCheck /></el-icon>
         一键已读
       </el-button>
@@ -40,9 +39,10 @@
 </template>
 
 <script setup lang="ts">
-import { ref } from "vue";
+import { ref, onMounted } from "vue";
 import { ElMessage } from "element-plus";
 import { CircleCheck } from "@element-plus/icons-vue";
+import { getNoticeList } from "@/api/modules/homeEntry.ts";
 
 interface NoticeItem {
   id: number;
@@ -52,22 +52,18 @@ interface NoticeItem {
   isRead: boolean;
 }
 
-const noticeList = ref<NoticeItem[]>([
-  {
-    id: 1,
-    title: "入驻店铺申请通知",
-    time: "2025/08/01 12:00",
-    content: "您在2025-01-01 12:12:12提交的入驻店铺申请,平台已受理,1-3个工作日将审核结果发送至应用内的消息—通知中,请注意查收。",
-    isRead: false
-  },
-  {
-    id: 2,
-    title: "入驻店铺申请通知",
-    time: "2025/08/01 12:00",
-    content: "您在2025-01-01 12:12:12提交的入驻店铺申请,平台已受理,1-3个工作日将审核结果发送至应用内的消息—通知中,请注意查收。",
-    isRead: true
+onMounted(() => {
+  getList();
+});
+
+const noticeList = ref<NoticeItem[]>([]);
+const getList = async () => {
+  let res = await getNoticeList({ pageNum: 1, pageSize: 10, receiverId: "15242687180" });
+  console.log(res);
+  if (res.code == "200") {
+    noticeList.value = res.data.records;
   }
-]);
+};
 
 const dialogVisible = ref(false);
 const currentNotice = ref<NoticeItem | null>(null);