Parcourir la source

wip:公众号页面

wangshan il y a 4 mois
Parent
commit
c7469ddb42
8 fichiers modifiés avec 1083 ajouts et 632 suppressions
  1. 4 4
      .npmrc
  2. 293 327
      package-lock.json
  3. 1 1
      package.json
  4. 10 0
      src/router.js
  5. 252 0
      src/views/huiju/wechatEdit.vue
  6. 132 0
      src/views/huiju/wechatIndex.vue
  7. 140 0
      src/views/huiju/wechatList.vue
  8. 251 300
      yarn.lock

+ 4 - 4
.npmrc

@@ -1,4 +1,4 @@
-registry=https://registry.npmmirror.com/
-@jianyu:registry=http://192.168.3.71:4873/
-@jy:registry=http://192.168.3.71:4873/
-element-ui:registry=http://192.168.3.71:4873/
+registry=http://172.20.100.235:14873/
+@jianyu:registry=http://172.20.100.235:14873/
+@jy:registry=http://172.20.100.235:14873/
+# element-ui:registry=http://172.20.100.235:14873/

Fichier diff supprimé car celui-ci est trop grand
+ 293 - 327
package-lock.json


+ 1 - 1
package.json

@@ -14,7 +14,7 @@
     "cascader-multi": "^2.0.3",
     "clipboard": "^2.0.11",
     "clipboard-polyfill": "^4.0.2",
-    "element-ui": "^2.15.16-rc",
+    "element-ui": "^2.15.23-rc",
     "iview": "^3.5.1",
     "jquery": "^3.5.1",
     "localStorage": "^1.0.4",

+ 10 - 0
src/router.js

@@ -112,6 +112,16 @@ const routes = [
         name: 'outServer',
         component: () => import('./views/outServer/outServer.vue')
     },
+    {
+      path: '/huiju/wechatList',
+      name: 'wechatList',
+      component: () => import('./views/huiju/wechatList.vue'),
+    },
+    {
+        path: '/huiju/wechatEdit',
+        name: 'wechatEdit',
+        component: () => import('./views/huiju/wechatEdit.vue'),
+    },
 ];
 
 // 路由自动加载

+ 252 - 0
src/views/huiju/wechatEdit.vue

@@ -0,0 +1,252 @@
+<template>
+  <div class="container">
+    <h2 class="mb-4" id="formTitle">{{ formTitle }}</h2>
+    <el-form :model="form" ref="postForm" :rules="rules" label-width="120px">
+      <el-form-item label="选择公众号推文" prop="articleId">
+        <div class="bordered-content">
+          <el-radio-group v-model="form.articleId" @change="handleArticleChange" v-if="!loading && paginatedArticles.length">
+            <div v-for="article in paginatedArticles" :key="article.id" class="article-item">
+              <el-radio :label="article.id" :disabled="article.disabled">
+                {{ article.title }} - {{ article.date }}
+              </el-radio>
+              <hr v-if="$index !== paginatedArticles.length - 1" class="divider" />
+            </div>
+          </el-radio-group>
+          <div v-else-if="loading" class="text-center"><i class="el-icon-loading"></i></div>
+          <div v-else class="text-center">暂无文章</div>
+        </div>
+        <div class="pagination-container">
+          <el-pagination
+            v-if="!loading && paginatedArticles.length"
+            :current-page.sync="currentArticlePage"
+            :page-size="articlePageSize"
+            :total="allArticles.length"
+            layout="prev, pager, next"
+            @current-change="handleArticlePageChange"
+          />
+        </div>
+      </el-form-item>
+
+      <el-form-item label="选择发送群组" prop="groupIds">
+        <div class="bordered-content group-container">
+          <el-checkbox-group v-model="form.groupIds" class="checkbox-group">
+            <div v-for="group in mockGroups" :key="group.id" class="group-item">
+              <el-checkbox :label="group.id">
+                {{ group.name }}
+              </el-checkbox>
+            </div>
+          </el-checkbox-group>
+        </div>
+      </el-form-item>
+
+      <el-form-item label="备注" prop="remarks">
+        <el-input v-model="form.remarks" type="textarea" :rows="3" resize="none" />
+      </el-form-item>
+
+      <el-form-item>
+        <div class="button-container">
+          <el-button @click="goBack">取消</el-button>
+          <el-button type="primary" @click="savePost(false)">保存</el-button>
+          <el-button type="success" @click="savePost(true)">发送</el-button>
+        </div>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'WechatEdit',
+  data() {
+    return {
+      accountId: this.$route.query.accountId || '',
+      postId: this.$route.query.postId || '',
+      currentArticlePage: 1,
+      articlePageSize: 5,
+      loading: false,
+      mockArticles: Array.from({ length: 15 }, (_, i) => ({
+        id: i + 1,
+        title: `文章${i + 1}`,
+        date: `2025-03-${String(i + 1).padStart(2, '0')}`,
+        disabled: false,
+      })),
+      mockGroups: [
+        { id: 1, name: '群组群组群组群组群组A' },
+        { id: 2, name: '群组B' },
+        { id: 3, name: '群组C' },
+        { id: 4, name: '群组D' },
+        { id: 5, name: '群组E' },
+        { id: 6, name: '群组F' },
+        { id: 7, name: '群组G' },
+        { id: 8, name: '群组H' },
+        { id: 9, name: '群组I' },
+        { id: 10, name: '群组J' },
+        { id: 11, name: '群组K' },
+        { id: 12, name: '群组L' },
+        { id: 13, name: '群组M' },
+        { id: 14, name: '群组N' },
+        { id: 15, name: '群组O' }, // 增加更多群组以测试滚动
+      ],
+      mockPosts: [],
+      form: {
+        articleId: '',
+        groupIds: [],
+        remarks: '',
+      },
+      rules: {
+        articleId: [{ required: true, message: '请选择一篇推文', trigger: 'change' }],
+        groupIds: [{ required: true, message: '请选择至少一个群组', trigger: 'change' }],
+      },
+      formTitle: '新建/编辑推文',
+    };
+  },
+  computed: {
+    allArticles() {
+      console.log('allArticles:', this.mockArticles, 'length:', this.mockArticles?.length);
+      return this.mockArticles || [];
+    },
+    paginatedArticles() {
+      if (!this.allArticles || !Array.isArray(this.allArticles)) {
+        console.warn('allArticles is not an array:', this.allArticles);
+        return [];
+      }
+      const start = Math.max(0, (this.currentArticlePage - 1) * this.articlePageSize);
+      const end = Math.min(start + this.articlePageSize, this.allArticles.length);
+      const result = this.allArticles.slice(start, end);
+      console.log('paginatedArticles:', result, 'start:', start, 'end:', end);
+      return result;
+    },
+  },
+  methods: {
+    handleArticlePageChange(page) {
+      this.currentArticlePage = page;
+    },
+    handleArticleChange(value) {
+      console.log('Selected article ID:', value);
+    },
+    async loadFormData() {
+      this.loading = true;
+      try {
+        if (!this.accountId) {
+          this.$message.warning('未选择公众号');
+          this.$router.push('/');
+          return;
+        }
+
+        if (this.postId) {
+          this.formTitle = '编辑推文';
+          const post = this.mockPosts.find((p) => p.id === parseInt(this.postId));
+          if (post) {
+            this.form = {
+              articleId: post.articleId.toString(),
+              groupIds: post.groupIds.map((id) => id.toString()),
+              remarks: post.remarks || '',
+            };
+            this.mockArticles.forEach((article) => {
+              article.disabled = article.id === post.articleId;
+            });
+          }
+        }
+      } catch (error) {
+        console.error('加载数据失败:', error);
+        this.$message.error('加载表单数据失败');
+      } finally {
+        this.loading = false;
+      }
+    },
+    async savePost(send = false) {
+      this.$refs['postForm'].validate(async (valid) => {
+        if (valid) {
+          try {
+            const postData = {
+              id: this.postId ? parseInt(this.postId) : this.mockPosts.length + 1,
+              accountId: parseInt(this.accountId),
+              articleId: parseInt(this.form.articleId),
+              groupIds: this.form.groupIds.map((id) => parseInt(id)),
+              remarks: this.form.remarks,
+              title: this.mockArticles.find((a) => a.id === parseInt(this.form.articleId)).title,
+              time: new Date().toISOString().slice(0, 10),
+              sender: '当前用户',
+              status: send ? '成功' : '待发送',
+            };
+
+            if (this.postId) {
+              const index = this.mockPosts.findIndex((p) => p.id === parseInt(this.postId));
+              this.mockPosts[index] = postData;
+            } else {
+              this.mockPosts.push(postData);
+            }
+
+            this.$message.success(send ? '发送成功' : '保存成功');
+            this.goBack();
+          } catch (error) {
+            console.error('保存/发送失败:', error);
+            this.$message.error('操作失败');
+          }
+        } else {
+          this.$message.error('请填写完整表单');
+        }
+      });
+    },
+    goBack() {
+      this.$router.push(`/huiju/wechatList?wcId=${this.accountId}`);
+    },
+  },
+  mounted() {
+    console.log('Initial mockArticles:', this.mockArticles);
+    this.loadFormData();
+  },
+  watch: {
+    '$route.query.accountId'(newId) {
+      this.accountId = newId || '';
+    },
+    '$route.query.postId'(newId) {
+      this.postId = newId || '';
+      this.loadFormData();
+    },
+  },
+};
+</script>
+
+<style scoped>
+.container {
+  padding: 20px;
+}
+.bordered-content {
+  border: 1px solid #dcdfe6;
+  padding: 15px;
+  border-radius: 4px;
+}
+.article-item {
+  margin-bottom: 20px;
+}
+.article-item:last-child {
+  margin-bottom: 0;
+}
+.divider {
+  border: 0;
+  border-top: 1px solid #dcdfe6;
+  margin: 10px 0;
+}
+.pagination-container {
+  display: flex;
+  justify-content: center;
+  margin-top: 20px;
+}
+.group-container {
+  max-height: 500px; /* 设置最大高度 */
+  overflow-y: auto; /* 超过高度时显示滚动条 */
+}
+.checkbox-group {
+  display: flex;
+  flex-wrap: wrap; /* 自动换行 */
+  gap: 15px; /* 群组之间的间距 */
+}
+.group-item {
+  flex: 0 0 auto; /* 防止收缩 */
+}
+.button-container {
+  display: flex;
+  justify-content: flex-end;
+}
+</style>

+ 132 - 0
src/views/huiju/wechatIndex.vue

@@ -0,0 +1,132 @@
+<template>
+  <div class="container">
+    <h2 class="title">公众号列表</h2>
+    <el-row :gutter="20">
+      <el-col
+          v-for="account in paginatedAccounts"
+          :key="account.id"
+          :span="8"
+          class="account-col"
+      >
+        <el-card
+            class="account-card"
+            shadow="hover"
+            @click.native="goToPosts(account.id)"
+        >
+          <div class="card-content">
+            <img :src="account.avatar" alt="头像" class="avatar" />
+            <div class="info">
+              <h5>{{ account.name }}</h5>
+              <p>{{ account.description }}</p>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+    <div class="pagination">
+      <el-pagination
+          :current-page.sync="currentPage"
+          :page-size="pageSize"
+          :total="mockAccounts.length"
+          layout="prev, pager, next"
+          @current-change="handlePageChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'AccountList',
+  data() {
+    return {
+      currentPage: 1,
+      pageSize: 6,
+      mockAccounts: Array.from({ length: 20 }, (_, i) => ({
+        id: i + 1,
+        name: `公众号${i + 1}`,
+        avatar: `https://via.placeholder.com/80?text=公众号${i + 1}`,
+        description: `这是公众号${i + 1}的简介`,
+      })),
+    };
+  },
+  computed: {
+    paginatedAccounts() {
+      const start = (this.currentPage - 1) * this.pageSize;
+      const end = start + this.pageSize;
+      return this.mockAccounts.slice(start, end);
+    },
+  },
+  methods: {
+    handlePageChange(page) {
+      this.currentPage = page;
+    },
+    goToPosts(accountId) {
+      // this.$router.push({
+      //   path: `/huiju/wechatList`,
+      //   query: {wcId: accountId},
+      // });
+      console.log('Navigating to wechatList with accountId:', accountId);
+    this.$router.push({
+      name: 'wechatList',
+      query: {wcId: accountId},
+    });
+    },
+    async loadAccounts() {
+      try {
+        // 模拟接口调用,未来可替换为真实 API
+        // const response = await fetch('/api/accounts');
+        // this.mockAccounts = await response.json();
+      } catch (error) {
+        console.error('加载公众号失败:', error);
+        this.$message.error('加载公众号列表失败');
+      }
+    },
+  },
+  mounted() {
+    this.loadAccounts();
+  },
+};
+</script>
+
+<style scoped>
+.container {
+  padding: 20px;
+}
+.title {
+  margin-bottom: 20px;
+  font-size: 24px;
+  font-weight: bold;
+}
+.account-col {
+  margin-bottom: 20px;
+}
+.account-card {
+  cursor: pointer;
+  height: 250px;
+}
+.card-content {
+  display: flex;
+  align-items: center;
+}
+.avatar {
+  width: 80px;
+  height: 80px;
+  object-fit: cover;
+  border-radius: 50%;
+  margin-right: 16px;
+}
+.info h5 {
+  margin: 0 0 8px 0;
+  font-size: 18px;
+}
+.info p {
+  margin: 0;
+  color: #666;
+}
+.pagination {
+  display: flex;
+  justify-content: center;
+  margin-top: 20px;
+}
+</style>

+ 140 - 0
src/views/huiju/wechatList.vue

@@ -0,0 +1,140 @@
+<template>
+  <div class="container">
+    <div class="header">
+      <h2>发送推文列表 (公众号 ID: {{ accountId || '未选择' }})</h2>
+      <el-button type="primary" @click.native="goToNewPost">新建发送</el-button>
+    </div>
+    <el-table :data="paginatedPosts" style="width: 100%" stripe>
+      <el-table-column prop="id" label="ID" width="80"></el-table-column>
+      <el-table-column prop="title" label="文章标题"></el-table-column>
+      <el-table-column prop="time" label="推送时间"></el-table-column>
+      <el-table-column prop="sender" label="发送人"></el-table-column>
+      <el-table-column prop="groups" label="发送群组">
+        <template slot-scope="scope">
+          {{ scope.row.groups.join(', ') }}
+        </template>
+      </el-table-column>
+      <el-table-column label="状态">
+        <template slot-scope="scope">
+          <el-tag
+            :type="getStatusType(scope.row.status)"
+            disable-transitions
+          >
+            {{ scope.row.status }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" width="120">
+        <template slot-scope="scope">
+          <el-button
+            size="small"
+            type="primary"
+            @click.native="editPost(scope.row.id)"
+          >编辑</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="pagination">
+      <el-pagination
+        :current-page.sync="currentPostPage"
+        :page-size="postPageSize"
+        :total="allPosts.length"
+        layout="prev, pager, next"
+        @current-change="handlePageChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'WechatList',
+  data() {
+    return {
+      accountId: this.$route.query.wcId || '',
+      currentPostPage: 1,
+      postPageSize: 10,
+      mockPosts: Array.from({ length: 30 }, (_, i) => ({
+        id: i + 1,
+        title: `文章标题${i + 1}`,
+        time: `2025-03-${String(i + 1).padStart(2, '0')}`,
+        sender: `用户${i % 3 + 1}`,
+        groups: [`群组${i % 2 + 1}`],
+        status: i % 3 === 0 ? '成功' : i % 3 === 1 ? '失败' : '待发送',
+      })),
+    };
+  },
+  computed: {
+    allPosts() {
+      console.log('Total posts count:', this.mockPosts.length, 'accountId:', this.accountId);
+      return this.mockPosts; // 移除过滤,直接使用全部数据
+    },
+    paginatedPosts() {
+      const start = (this.currentPostPage - 1) * this.postPageSize;
+      const end = Math.min(start + this.postPageSize, this.allPosts.length); // 防止越界
+      const result = this.allPosts.slice(start, end);
+      console.log('Paginated posts length:', result.length, 'start:', start, 'end:', end);
+      return result;
+    },
+  },
+  methods: {
+    handlePageChange(page) {
+      this.currentPostPage = page;
+    },
+    getStatusType(status) {
+      return status === '成功' ? 'success' : status === '失败' ? 'danger' : 'warning';
+    },
+    editPost(id) {
+      this.$router.push({
+        name: 'wechatEdit',
+        query: {
+          accountId: this.accountId,
+          postId:id
+        },
+      });
+    },
+    goToNewPost() {
+      this.$router.push({
+        name: 'wechatEdit',
+        query: {
+          accountId: this.accountId
+        },
+      });
+    },
+  },
+  mounted() {
+    if (!this.accountId) {
+      this.$message.warning('未选择公众号');
+      this.$router.push('/huiju/wechatIndex');
+    } else {
+      console.log('Received accountId:', this.accountId, 'postPageSize:', this.postPageSize);
+    }
+  },
+  watch: {
+    '$route.query.wcId'(newId) {
+      this.accountId = newId || '';
+      if (!this.accountId) {
+        this.$message.warning('未选择公众号');
+        this.$router.push('/huiju/wechatIndex');
+      }
+    },
+  },
+};
+</script>
+
+<style scoped>
+.container {
+  padding: 20px;
+}
+.header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
+.pagination {
+  display: flex;
+  justify-content: center;
+  margin-top: 20px;
+}
+</style>

Fichier diff supprimé car celui-ci est trop grand
+ 251 - 300
yarn.lock


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff