ext.liuqiwen3 vor 1 Tag
Ursprung
Commit
3a42799cc4
1 geänderte Dateien mit 399 neuen und 0 gelöschten Zeilen
  1. 399 0
      pages/merchantCenter/productCenter.vue

+ 399 - 0
pages/merchantCenter/productCenter.vue

@@ -0,0 +1,399 @@
+<template>
+  <view class="container">
+    <!-- 搜索栏 -->
+    <view class="search-bar">
+<!--      <up-search placeholder="搜索商品名称" shape="square" :clearabled="true"-->
+<!--                 height="36" bgColor="#F9F7F0" :showAction="false" v-model="searchVal"-->
+<!--                 @clear="onClear" @search="onSearch"-->
+<!--                 :focus="isFocus" @focus="onFocus" @blur="onBlur" ></up-search>-->
+      <view class="search-bar-con">
+        <view class="search-input-wrapper">
+          <uni-icons class="search-icon" type="search" size="18" color="#999"></uni-icons>
+          <input
+              class="search-input"
+              v-model="searchVal"
+              placeholder="请输入搜索内容"
+              placeholder-class="placeholder"
+              @input="onSearch"
+              @confirm="onSearch"
+              :focus="isFocus"
+          />
+          <view v-if="searchVal" class="clear-btn" @click="onClear">
+            <uni-icons type="clear" size="18" color="#999"></uni-icons>
+          </view>
+        </view>
+      </view>
+    </view>
+
+
+    <!-- 商品列表 -->
+    <view class="product-list">
+      <view class="product-card" v-for="(item, index) in goodsList" :key="index">
+        <view class="product-header">
+          <image class="product-image" :src="item.image" mode="aspectFit" />
+          <view class="product-info">
+            <view class="nameweight">
+              <text class="product-name">{{ item.storeName }}</text>
+              <text class="product-weight">{{ item.weight }}g</text>
+            </view>
+            <view class="nameweight">
+              <view class="price-info">
+                <text class="label">工费</text>
+                <view class="value"><text class="unit">¥</text>{{ item.totalLaborCost }}<text class="unit">/g</text></view>
+              </view>
+              <view class="price-info">
+                <text class="label">附加费</text>
+                <view class="value"><text class="unit">¥</text>{{ item.additionalAmount }}</view>
+              </view>
+            </view>
+            <view class="product-stats">
+              <text class="stat">销量:{{ Number(item.sales || 0) + Number(item.ficti || 0) }}</text>
+              <text class="stat">库存:{{ item.stock }}</text>
+            </view>
+          </view>
+        </view>
+
+        <view class="action-buttons">
+          <button class="btn btn-offline" v-show="params.isShow==1" @click="OffShellFn(item,index)">下架</button>
+          <button class="btn btn-offline" v-show="params.isShow==0" @click="PutOnShellFn(item,index)">上架</button>
+          <button class="btn btn-edit" @click="toEditProduct(item)">编辑</button>
+        </view>
+      </view>
+      <view class="loadingicon acea-row row-center-wrapper" v-if="goodScroll">
+        <text
+            class="loading iconfont icon-jiazai"
+            :hidden="loading == false"
+        ></text>
+      </view>
+      <view class="no-data" v-if="isNoDataState">
+        <image
+            src="https://my-go-easy-im.oss-cn-shenzhen.aliyuncs.com/goeasy-im-%E6%B0%B4%E8%B4%9D%E5%95%86%E5%9F%8E/zhanwu_20250827104005_1720_6.png"
+        />
+      </view>
+      <view class="mores-txt flex" v-if="!goodScroll && !isNoDataState">
+        <text>我是有底线的</text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script setup>
+import {computed, ref} from 'vue'
+import { onLoad, onShow, onReachBottom } from "@dcloudio/uni-app";
+import { productsList,productPutOnShell,productOffShell } from "@/api/merchant.js";
+import { useAppStore } from "@/stores/app";
+
+const appStore = useAppStore();
+
+const tabList = ref([
+  {name:'销售中',code:1},
+  {name:'已下架',code:0}
+])
+const searchVal = ref('')
+const goodsList = ref([]);
+const goodType = ref(1);
+// Pagination
+const params = ref({
+  page: 1,
+  limit: 10,
+  isShow:1,
+});
+const loading = ref(false);
+const goodScroll = ref(true);
+const merchantInfo = ref({})
+
+const isFocus = ref(false)
+
+const isNoDataState = computed(() => {
+  return goodsList.value.length === 0 && !loading.value;
+});
+
+
+onShow(() => {
+  merchantInfo.value = appStore.userInfo.merchant;
+  getGroomList()
+})
+
+const onFocus = () => {
+  console.log('获取焦点')
+  isFocus.value = true
+}
+
+const onBlur = () => {
+  console.log('失去焦点')
+  // 不要立即设置为false,避免焦点闪烁
+  setTimeout(() => {
+    isFocus.value = false
+  }, 200)
+}
+const tabChange = (item) => {
+  console.log('item',item)
+  goodsList.value = [];
+  loading.value = false;
+  goodScroll.value = true;
+  params.value.isShow = item.code;
+  params.value.page = 1;
+  getGroomList();
+}
+const onSearch = () => {
+  goodsList.value = [];
+  loading.value = false;
+  goodScroll.value = true;
+  params.value.page = 1;
+  getGroomList();
+}
+// 清除搜索内容
+const onClear = () => {
+  console.log('清除搜索内容');
+  searchVal.value = ''; // 手动清空关键词
+  // 如果需要清除后立即刷新列表,可以调用搜索
+  onSearch();
+}
+const getGroomList = async () => {
+  if (!goodScroll.value) return;
+  try {
+    loading.value = true;
+    params.value.merchantId = merchantInfo.value.id;
+    params.value.keyword = searchVal.value;
+    const { data } = await productsList(params.value);
+    goodsList.value = [...goodsList.value, ...data.list] || [];
+    goodScroll.value = data.list.length >= params.value.limit;
+    params.value.page++;
+  } catch (err) {
+    console.error(err);
+  } finally {
+    loading.value = false;
+  }
+};
+async function OffShellFn(obj,index) {
+  const {code} = await productOffShell(obj.id);
+  if(code == 200){
+    uni.showToast({ title: "操作成功", icon: "none" });
+    goodsList.value.splice(index,1);
+  }
+}
+async function PutOnShellFn(obj,index) {
+  const {code} = await productPutOnShell(obj.id);
+  if(code == 200){
+    uni.showToast({ title: "操作成功", icon: "none" });
+    goodsList.value.splice(index,1);
+  }
+
+}
+function toEditProduct (obj){
+  uni.navigateTo({
+    url:`pages/merchantCenter/releaseProduct?id=${obj.id}`
+  })
+}
+onReachBottom(() => {
+  getGroomList();
+});
+</script>
+
+<style lang="scss" scoped>
+
+/* 搜索栏样式 */
+.search-bar {
+  background: #fff;
+  padding: 30rpx 30rpx 0;
+}
+
+.search-input {
+  width: 100%;
+  height: 60rpx;
+  font-size: 28rpx;
+}
+
+/* 标签页样式 */
+.tabs {
+  display: flex;
+  background: white;
+  border-radius: 10rpx;
+  margin-bottom: 20rpx;
+}
+
+.tab {
+  flex: 1;
+  text-align: center;
+  padding: 20rpx;
+  font-size: 28rpx;
+  color: #666;
+}
+
+.tab.active {
+  color: #333;
+  font-weight: bold;
+  border-bottom: 4rpx solid #333;
+}
+.product-list{
+  padding: 30rpx;
+  box-sizing: border-box;
+}
+/* 商品卡片样式 */
+.product-card {
+  background: #fff;
+  border-radius: 16rpx;
+  padding: 30rpx;
+  margin-bottom: 20rpx;
+}
+
+.product-header {
+  display: flex;
+  margin-bottom: 20rpx;
+}
+
+.product-image {
+  width: 120rpx;
+  height: 120rpx;
+  border-radius: 10rpx;
+  margin-right: 20rpx;
+}
+
+.product-info {
+  flex: 1;
+}
+
+.nameweight{
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20rpx;
+}
+.product-name {
+  font-size: 28rpx;
+  color: #333;
+  display: block;
+}
+.product-weight {
+    background-color: rgba(197, 128, 3, 0.10);
+    color: #C58003;
+    font-size: 24rpx;
+    padding: 8rpx 16rpx;
+    border-radius: 8rpx;
+    float: right;
+}
+
+.price-info {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 8rpx;
+}
+
+.label {
+  font-size: 24rpx;
+  color: #666666;
+}
+
+.value {
+  color: #FD5F3C;
+  font-size: 32rpx;
+  .unit{
+    font-size: 24rpx;
+  }
+}
+
+/* 销售数据样式 */
+.product-stats {
+  display: flex;
+  margin-bottom: 20rpx;
+  gap: 10rpx;
+}
+
+.stat {
+  font-size: 24rpx;
+  color: #666;
+  padding: 10rpx;
+  background-color: #F5F7FA;
+  border-radius: 8rpx;
+}
+
+/* 操作按钮样式 */
+.action-buttons {
+  display: flex;
+  justify-content: space-between;
+  gap: 30rpx;
+}
+
+.btn {
+  flex: 1;
+  height: 60rpx;
+  line-height: 60rpx;
+  border-radius: 8rpx;
+  font-size: 28rpx;
+  border: none;
+}
+
+
+.btn-offline {
+  background: #F5F7FA;
+  color: #333;
+}
+
+.btn-edit {
+  background: #F8C008;
+  color: #333;
+}
+.no-data {
+  margin: 150rpx auto 0;
+  text-align: center;
+
+  img {
+    width: 65%;
+    height: auto;
+  }
+}
+.mores-txt {
+  width: 100%;
+  align-items: center;
+  justify-content: center;
+  height: 70rpx;
+  color: #999;
+  font-size: 24rpx;
+
+  .iconfont {
+    margin-top: 2rpx;
+    font-size: 20rpx;
+  }
+}
+.search-bar-con {
+  display: flex;
+  align-items: center;
+  background-color: #fff;
+  border-bottom: 1rpx solid #eee;
+}
+
+.search-input-wrapper {
+  flex: 1;
+  position: relative;
+  display: flex;
+  align-items: center;
+  background-color: #F9F7F0;
+  border-radius: 16rpx;
+  height: 72rpx;
+  line-height: 72rpx;
+  padding: 0 20rpx;
+  box-sizing: border-box;
+}
+
+.search-icon {
+  margin-right: 20rpx;
+}
+
+.search-input {
+  flex: 1;
+  height: 100%;
+  font-size: 28rpx;
+  color: #333;
+}
+
+.placeholder {
+  color: #999;
+  font-size: 28rpx;
+}
+
+.clear-btn {
+  padding: 10rpx;
+  margin-left: 10rpx;
+}
+
+</style>