longmh 10 сар өмнө
parent
commit
14f927948e

+ 86 - 0
src/api/dgtmedicine/ad/index.ts

@@ -0,0 +1,86 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { AdVO, AdForm, AdQuery } from '@/api/dgtmedicine/ad/types';
+
+/**
+ * 查询广告列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listAd = (query?: AdQuery): AxiosPromise<AdVO[]> => {
+  return request({
+    url: '/dgtmedicine/ad/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询广告详细
+ * @param id
+ */
+export const getAd = (id: string | number): AxiosPromise<AdVO> => {
+  return request({
+    url: '/dgtmedicine/ad/getInfo/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增广告
+ * @param data
+ */
+export const addAd = (data: AdForm) => {
+  return request({
+    url: '/dgtmedicine/ad/add',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改广告
+ * @param data
+ */
+export const updateAd = (data: AdForm) => {
+  return request({
+    url: '/dgtmedicine/ad/edit',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 删除广告
+ * @param id
+ */
+export const delAd = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/dgtmedicine/ad/remove/' + id,
+    method: 'get'
+  });
+};
+
+
+/**
+ * 上架广告
+ * @param id
+ */
+export const publishAd = (id: string | number) => {
+  return request({
+    url: '/dgtmedicine/ad/publish/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 下架广告
+ * @param id
+ */
+export const unpublishAd = (id: string | number) => {
+  return request({
+    url: '/dgtmedicine/ad/unpublish/' + id,
+    method: 'get'
+  });
+};

+ 226 - 0
src/api/dgtmedicine/ad/types.ts

@@ -0,0 +1,226 @@
+export interface AdVO {
+  /**
+   * 
+   */
+  id: string | number;
+
+  /**
+   * 广告标题
+   */
+  title: string;
+
+  /**
+   * 广告类型
+   */
+  adType: string;
+
+  /**
+   * 广告位置
+   */
+  adPosition: string;
+
+  /**
+   * 广告链接
+   */
+  adUrl: string;
+
+  /**
+   * 广告图片
+   */
+  adImg: string;
+
+  /**
+   * 广告文字
+   */
+  adText: string;
+
+  /**
+   * 广告页面
+   */
+  adPage: string;
+
+  /**
+   * 渲染方式
+   */
+  style: string;
+
+  /**
+   * 状态
+   */
+  status: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+  /**
+   * 生效日期
+   */
+  validFrom: string;
+
+  /**
+   * 失效日期
+   */
+  validUntil: string;
+
+  /**
+   * 合作伙伴ID
+   */
+  partnerId: string | number;
+
+  /**
+   * 创建人
+   */
+  createBy: string;
+
+  /**
+   * 创建时间
+   */
+  createTime: string;
+
+  /**
+   * 更新时间
+   */
+  updateTime: string;
+
+}
+
+export interface AdForm extends BaseEntity {
+  /**
+   * 
+   */
+  id?: string | number;
+
+  /**
+   * 广告标题
+   */
+  title?: string;
+
+  /**
+   * 广告类型
+   */
+  adType?: string;
+
+  /**
+   * 广告位置
+   */
+  adPosition?: string;
+
+  /**
+   * 广告链接
+   */
+  adUrl?: string;
+
+  /**
+   * 广告图片
+   */
+  adImg?: string;
+
+  /**
+   * 广告文字
+   */
+  adText?: string;
+
+  /**
+   * 广告页面
+   */
+  adPage?: string;
+
+  /**
+   * 渲染方式
+   */
+  style?: string;
+
+  /**
+   * 状态
+   */
+  status?: string;
+
+  /**
+   * 生效日期
+   */
+  validFrom?: string | number;
+
+  /**
+   * 失效日期
+   */
+  validUntil?: string | number;
+
+  /**
+   * 合作伙伴ID
+   */
+  partnerId?: string | number;
+
+}
+
+export interface AdQuery extends PageQuery {
+
+  /**
+   * 广告标题
+   */
+  title?: string;
+
+  /**
+   * 广告类型
+   */
+  adType?: string;
+
+  /**
+   * 广告位置
+   */
+  adPosition?: string;
+
+  /**
+   * 广告链接
+   */
+  adUrl?: string;
+
+  /**
+   * 广告图片
+   */
+  adImg?: string;
+
+  /**
+   * 广告文字
+   */
+  adText?: string;
+
+  /**
+   * 广告页面
+   */
+  adPage?: string;
+
+  /**
+   * 渲染方式
+   */
+  style?: string;
+
+  /**
+   * 状态
+   */
+  status?: string;
+
+  /**
+   * 生效日期
+   */
+  validFrom?: string | number;
+
+  /**
+   * 失效日期
+   */
+  validUntil?: string | number;
+
+  /**
+   * 合作伙伴ID
+   */
+  partnerId?: string | number;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 169 - 0
src/views/dgtmedicine/ad/adAdd.vue

@@ -0,0 +1,169 @@
+<template>
+    <div class="p-3">
+        <div class="bg-fff flex1 ov-hd d-flex flex-cln">
+            <div class="d-flex a-c pd-16 border-bottom">
+                <div class="f-s-20 c-333 f-w-7 mr-10">{{ router.currentRoute.value.query.title || '新增广告' }}</div>
+                <el-button @click="router.go(-1)" type="primary" text>
+                    <el-icon>
+                        <Back />
+                    </el-icon>
+                    返回上一级
+                </el-button>
+            </div>
+            <div class="flex1 over-auto">
+                <el-form ref="formRef" label-width="auto" label-position="top" :model="form" :rules="rules" :disabled="disable">
+                    <div class="pd-16 border-bottom">
+                        <el-row :gutter="90">
+                            <el-col :span="8">
+                                <el-form-item label="广告标题:" prop="title">
+                                    <el-input v-model="form.title" clearable placeholder="请输入标题"></el-input>
+                                </el-form-item>
+                            </el-col>
+                            <el-col :span="8">
+                                <el-form-item label="页面中位置:" prop="adPosition">
+                                    <el-select v-model="form.adPosition" clearable placeholder="请选择页面">
+                                        <el-option v-for="item in dm_ad_position" :key="item.value" :label="item.label" :value="item.value" />
+                                    </el-select>
+                                </el-form-item>
+                            </el-col>
+                        </el-row>
+                        <el-row :gutter="90">
+                            <el-col :span="8">
+                                <el-form-item label="广告样式:" prop="style">
+                                    <el-select v-model="form.style" clearable placeholder="请选择广告样式">
+                                        <el-option v-for="item in dm_ad_style" :key="item.value" :label="item.label" :value="item.value" />
+                                    </el-select>
+                                </el-form-item>
+                            </el-col>
+                            <el-col :span="8">
+                                <el-form-item label="链接类型:" prop="adType">
+                                    <el-select v-model="form.adType" clearable placeholder="请选择链接类型">
+                                        <el-option v-for="item in dm_ad_type" :key="item.value" :label="item.label" :value="item.value" />
+                                    </el-select>
+                                </el-form-item>
+                            </el-col>
+                        </el-row>
+                        <el-row :gutter="90">
+                            <el-col :span="8">
+                                <el-form-item label="生效日期:" prop="validFrom">
+                                    <el-date-picker style="width: 100%;" v-model="form.validFrom" type="date" placeholder="选择日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" :disabled="disable" />
+                                </el-form-item>
+                            </el-col>
+                            <el-col :span="8">
+                                <el-form-item label="失效日期:" prop="validUntil">
+                                    <el-date-picker style="width: 100%;" v-model="form.validUntil" type="date" placeholder="选择日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" :disabled="disable" />
+                                </el-form-item>
+                            </el-col>
+                        </el-row>
+                        <el-row :gutter="90">
+                            <el-col :span="8">
+                                <el-form-item label="放置页面:" prop="adPage">
+                                    <el-select v-model="form.adPage" clearable placeholder="请选择页面">
+                                        <el-option v-for="item in dm_ad_page" :key="item.value" :label="item.label" :value="item.value" />
+                                    </el-select>
+                                </el-form-item>
+                            </el-col>
+                            <el-col :span="8">
+                                <el-form-item label="备注:" prop="remark">
+                                    <el-input v-model="form.remark" clearable placeholder="请输入备注"></el-input>
+                                </el-form-item>
+                            </el-col>
+                        </el-row>
+                        <el-row :gutter="90">
+                            <el-col :span="8">
+                                <el-form-item label="跳转路径:" prop="adUrl">
+                                    <el-input v-model="form.adUrl" placeholder="请输入跳转路径" :disabled="disable" :clearable="true" :show-word-limit="true" />
+                                </el-form-item>
+                            </el-col>
+                            <el-col :span="8">
+                                <el-form-item label="广告文字:" prop="adText">
+                                    <el-input v-model="form.adText" placeholder="请输入广告文字" :disabled="disable" :clearable="true" :show-word-limit="true" />
+                                </el-form-item>
+                            </el-col>
+                        </el-row>
+                        <el-row :gutter="90">
+                            <el-col :span="8">
+                                <el-form-item label="广告图:" prop="adImg">
+                                    <imageUpload v-model="form.adImg" :limit="1" isString :isShowTip="false"></imageUpload>
+                                </el-form-item>
+                            </el-col>
+                        </el-row>
+                    </div>
+                </el-form>
+            </div>
+            <div class="d-flex a-c j-c pd-16">
+                <el-button @click="router.go(-1)">取消</el-button>
+                <el-button @click="save" color="#0079fe" :disabled="disable">暂存</el-button>
+                <el-button @click="submitGround" type="warning" :disabled="disable">立即上架</el-button>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup name="MedicineNews-add" lang="ts">
+import { ref, reactive, onMounted } from 'vue';
+import { debounce } from 'lodash';
+import { getAd , addAd, updateAd, publishAd as publishAdApi,unpublishAd as unpublishAdApi} from '@/api/dgtmedicine/ad';
+import { useRouter } from 'vue-router';
+import { title } from 'process';
+import { any } from 'vue-types';
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { news_status,dm_ad_type,dm_ad_position,dm_ad_page,dm_ad_style } = toRefs<any>(proxy?.useDict('news_status',
+    'dm_ad_type','dm_ad_position','dm_ad_page','dm_ad_style'));
+const router = useRouter();
+const form = ref({
+    id: undefined,
+    title: '',
+    adImg: '',
+    validFrom: '',
+    validUntil: '',
+    adType: '',
+    adText: '',
+    adPage: '',
+    adUrl: '',
+    remark: '',
+    adPosition:''
+});
+const rules = reactive({
+    title: [
+        { required: true, message: '请输入标题', trigger: 'blur' }
+    ],
+    content: [
+        { required: true, message: '请输入内容', trigger: 'blur' }
+    ]
+});
+const formRef = ref();
+const varietyOptions = ref([]);
+
+const save = debounce(async () => {
+    await formRef.value.validate();
+    const res = form.value.id ? await updateAd(form.value) : await addAd(form.value);
+    if (res && res.code === 200) {
+        router.go(-1);
+    }
+}, 500);
+
+const submitGround = debounce(async () => {
+    await formRef.value.validate();
+    const res = form.value.id ? await updateAd(form.value) : await addAd(form.value);
+    if (res && res.code === 200) {
+        await publishAdApi(res.data.id);
+        router.go(-1);
+    }
+}, 500);
+const fetchDetail = async (id) => {
+    const res = await getAd(id);
+    if (res && res.code === 200) {
+        form.value = res.data;
+    }
+};
+const disable = ref(false);
+onMounted(() => {
+    const id = router.currentRoute.value.query.id;
+    disable.value = router.currentRoute.value.query.disable == '1'
+    if (id) {
+        // 编辑
+        fetchDetail(id);
+    }
+});
+</script>

+ 201 - 0
src/views/dgtmedicine/ad/index.vue

@@ -0,0 +1,201 @@
+<template>
+    <div class="p-3">
+        <div class="bg-fff flex1 ov-hd d-flex flex-cln" v-show="showSearch">
+            <div class="pd-16 border-bottom">
+                <div class="f-s-20 c-333 f-w-7 mb-10">广告管理</div>
+                <div class="d-flex">
+                    <div class="mr-40">
+                        <el-button type="primary" @click="handleAdd">新增</el-button>
+                    </div>
+                    <div class="flex1 ov-hd d-flex j-ed">
+                        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="auto">
+                            <el-form-item label="标题" prop="title">
+                                <el-input v-model="queryParams.title" placeholder="请输入广告标题" clearable style="width: 180px" @keyup.enter="handleQuery" />
+                            </el-form-item>
+                            <el-form-item label="发布时间" prop="dateRange">
+                                <div class="d-flex" style="width: 180px">
+                                    <DateRange v-model="queryParams.dateRange" v-model:start-date="queryParams.startDate" v-model:end-date="queryParams.endDate"></DateRange>
+                                </div>
+                            </el-form-item>
+                            <el-form-item label="状态" prop="newsStatus">
+                                <el-select style="width: 140px" v-model="queryParams.status" clearable placeholder="请选择状态">
+                                    <el-option v-for="item in news_status" :key="item.value" :label="item.label" :value="item.value" />
+                                </el-select>
+                            </el-form-item>
+                            <el-form-item>
+                                <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+                                <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+                            </el-form-item>
+                        </el-form>
+                    </div>
+                </div>
+            </div>
+
+            <div class="d-flex flex1 ov-hd flex-cln pd-16">
+                <div class="pd-8"></div>
+                <div class="flex1 ov-hd">
+                    <vxe-table :loading="loading" border :data="adList" min-height="0" max-height="100%">
+                        <vxe-column title="序号" align="center" type="seq" width="60" :formatter="colNoData" />
+                        <vxe-column title="广告图片" align="center" field="adImg" :formatter="colNoData">
+                            <template #default="{ row }">
+                                <image-preview :src="row.adImg" :width="80" :height="70" />
+                            </template>
+                        </vxe-column>
+                        <vxe-column title="广告标题" align="center" field="title" :formatter="colNoData" />
+                        <vxe-column title="放置页面" align="center" field="adPage" :formatter="colNoData">
+                            <template #default="{ row }">
+                                <dict-tag :options="dm_ad_page" :value="row.adPage" />
+                            </template>
+                        </vxe-column>
+                        <vxe-column title="跳转方式" align="center" field="adPosition" :formatter="colNoData">
+                            <template #default="{ row }">
+                                <dict-tag :options="dm_ad_type" :value="row.adType" />
+                            </template>
+                        </vxe-column>
+                        <vxe-column title="广告样式" align="center" field="style" :formatter="colNoData">
+                            <template #default="{ row }">
+                                <dict-tag :options="dm_ad_style" :value="row.style" />
+                            </template>
+                        </vxe-column>
+                        <vxe-column title="广告位置" align="center" field="adPosition" :formatter="colNoData">
+                            <template #default="{ row }">
+                                <dict-tag :options="dm_ad_position" :value="row.adPosition" />
+                            </template>
+                        </vxe-column>
+                        <vxe-column title="生效日期" align="center" field="validFrom" :formatter="colNoData">
+                            <template #default="{ row }">
+                                <span>{{ parseTime(row.validFrom, '{y}-{m}-{d}') }}</span>
+                            </template>
+                        </vxe-column>
+                        <vxe-column title="失效日期" align="center" field="validUntil">
+                            <template #default="{ row }">
+                                <span>{{ parseTime(row.validUntil, '{y}-{m}-{d}') }}</span>
+                            </template>
+                        </vxe-column>
+                        <vxe-column title="操作人" align="center" field="createByName" :formatter="colNoData" />
+                        <vxe-column title="操作时间" align="center" field="createTime" :formatter="colNoData" />
+                        <vxe-column title="状态" align="center" field="status">
+                            <template #default="{ row }">
+                                <dict-tag :options="news_status" :value="row.status" />
+                            </template>
+                        </vxe-column>
+                        <vxe-column title="操作" width="250" align="center" fixed="right">
+                            <template #default="{ row }">
+                                <el-button type="text" size="small" @click="row.status === '1' ? unpublishAd(row) : publishAd(row)">
+                                    {{ row.status === '1' ? '下架' : '上架' }}
+                                </el-button>
+                                <el-button type="text" size="small" @click="handleUpdate(row)">编辑</el-button>
+                                <el-button type="text" size="small" @click="viewAddDetail(row)">详情</el-button>
+                                <el-button type="text" size="small" @click="handleDelete(row)">删除</el-button>
+                            </template>
+                        </vxe-column>
+                    </vxe-table>
+                </div>
+                <pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup name="AdManagement" lang="ts">
+import { listAd, getAd, delAd, addAd, updateAd, publishAd as publishAdApi,unpublishAd as unpublishAdApi} from '@/api/dgtmedicine/ad';
+import { ElMessageBox, ElMessage } from 'element-plus';
+import { colNoData } from '@/utils/noData';
+import { DateRange } from '@/views/models/index';
+
+const loading = ref(true);
+const showSearch = ref(true);
+const total = ref(0);
+const router = useRouter();
+const queryFormRef = ref<ElFormInstance>();
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { news_status,dm_ad_type,dm_ad_position,dm_ad_page,dm_ad_style } = toRefs<any>(proxy?.useDict('news_status',
+    'dm_ad_type','dm_ad_position','dm_ad_page','dm_ad_style'));
+const adList = ref<any[]>([]);
+const queryParams = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  title: '',
+  status: '',
+  adPosition: '',
+});
+
+const getList = async () => {
+  loading.value = true;
+  const res = await listAd(queryParams);
+  adList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+};
+
+const handleQuery = () => {
+  queryParams.pageNum = 1;
+  getList();
+};
+
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+};
+
+/** 广告新增   */
+const handleAdd = (row) => {
+  router.push({ path: `adAdd`, query: { id: row.id ,title:'新增广告'} });
+};
+
+/** 广告详情 */
+const viewAddDetail = (row) => {
+    router.push({ path: `adAdd`, query: { id: row.id, disable: '1' ,title:'广告详情'} });
+};
+
+/** 上架广告 */
+const publishAd = async (row) => {
+  loading.value = true;
+    try {
+        const res = await publishAdApi(row.id); // Replace with your API call
+        if (res) {
+            ElMessage.success('新闻已上架');
+            getList();
+        }
+    } catch (error) {
+        ElMessage.error('上架失败');
+    }
+    loading.value = false;
+};
+
+/** 下架广告 */
+const unpublishAd = async (row) => {
+  loading.value = true;
+    try {
+        const res = await unpublishAdApi(row.id); // Replace with your API call
+        if (res) {
+            ElMessage.success('新闻已下架');
+            getList();
+        }
+    } catch (error) {
+        ElMessage.error('下架失败');
+    }
+    loading.value = false;
+};
+
+const handleUpdate = async (row) => {
+  router.push({ path: `adAdd`, query: { id: row.id ,title:'编辑广告'} });
+
+};
+
+const handleDelete = async (row) => {
+  ElMessageBox.confirm(`确认要删除广告 "${row.title}" 吗?`, '删除提示', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning',
+  }).then(async () => {
+    await delAd(row.id);
+    ElMessage.success('删除成功');
+    getList();
+  });
+};
+
+onMounted(() => {
+  getList();
+});
+</script>

+ 1 - 1
src/views/dgtmedicine/news/medicinenews/detail.vue

@@ -60,4 +60,4 @@ const getDetail = async () => {
 onMounted(() => {
     getDetail();
 });
-</script></el-descriptions-item></template>
+</script>

+ 56 - 14
src/views/dgtmedicine/news/medicinenews/index.vue

@@ -10,14 +10,11 @@
                     <div class="flex1 ov-hd d-flex j-ed">
                         <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="auto">
                             <el-form-item label="标题" prop="newsTitle">
-                                <el-input v-model="queryParams.newsTitle" placeholder="请输入标题" clearable style="width: 180px"
-                                    @keyup.enter="handleQuery" />
+                                <el-input v-model="queryParams.newsTitle" placeholder="请输入标题" clearable style="width: 180px" @keyup.enter="handleQuery" />
                             </el-form-item>
                             <el-form-item label="状态" prop="newsStatus">
-                                <el-select style="width: 140px" v-model="queryParams.newsStatus" clearable
-                                    placeholder="请选择状态">
-                                    <el-option v-for="item in news_status" :key="item.value" :label="item.label"
-                                        :value="item.value" />
+                                <el-select style="width: 140px" v-model="queryParams.newsStatus" clearable placeholder="请选择状态">
+                                    <el-option v-for="item in news_status" :key="item.value" :label="item.label" :value="item.value" />
                                 </el-select>
                             </el-form-item>
                             <el-form-item>
@@ -40,10 +37,11 @@
                                 <div v-if="row.variety?.length">
                                     <el-tag>已关联品种({{ row.variety?.length }})</el-tag>
                                 </div>
-                                <div v-else>无</div>
+                                <div v-else><el-tag>已关联品种(0)</el-tag></div>
+                                <el-button type="text" @click="bindVariety(row)">绑定品种</el-button>
                             </template>
                         </vxe-column>
-                        <vxe-column title="操作人" align="center" field="createName" :formatter="colNoData" />
+                        <vxe-column title="操作人" align="center" field="createByName" :formatter="colNoData" />
                         <vxe-column title="操作时间" align="center" field="createTime" :formatter="colNoData" />
                         <vxe-column title="状态" align="center" field="newsStatus">
                             <template #default="{ row }">
@@ -52,8 +50,7 @@
                         </vxe-column>
                         <vxe-column title="操作" width="250" align="center" fixed="right">
                             <template #default="{ row }">
-                                <el-button type="text" size="small"
-                                    @click="row.newsStatus === '1' ? unpublishNews(row) : publishNews(row)">
+                                <el-button type="text" size="small" @click="row.newsStatus === '1' ? unpublishNews(row) : publishNews(row)">
                                     {{ row.newsStatus === '1' ? '下架' : '上架' }}
                                 </el-button>
                                 <el-button type="text" size="small" @click="editNews(row)">编辑</el-button>
@@ -63,26 +60,42 @@
                         </vxe-column>
                     </vxe-table>
                 </div>
-                <pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
-                    @pagination="getList" />
+                <pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
             </div>
         </div>
     </div>
+    <el-dialog title="选择品种" v-model="showVarietyDialog" width="600px">
+        <div>
+            <el-select v-model="form.variety" filterable multiple clearable placeholder="请选择品种">
+                <el-option v-for="item in varietyOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
+            </el-select>
+        </div>
+        <div class="dialog-footer">
+            <el-button @click="showVarietyDialog = false">取消</el-button>
+            <el-button type="primary" @click="edit">确定</el-button>
+        </div>
+    </el-dialog>
 </template>
 
 <script setup name="MedicineNews" lang="ts">
 import { colNoData } from '@/utils/noData';
-import { publishNews as publishNewsApi, unpublishNews as unpublishNewsApi, removeNews, fetchNewsList } from '@/api/dgtmedicine/news';
+import {Edit} from '@element-plus/icons-vue'
+import { getMedicineList } from '@/api/dgtmedicine/variety';
+import { editNews as editNewsApi,publishNews as publishNewsApi, unpublishNews as unpublishNewsApi, removeNews, fetchNewsList } from '@/api/dgtmedicine/news';
 const router = useRouter();
+import { debounce } from 'lodash';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const { news_status } = toRefs<any>(proxy?.useDict('news_status'));
 const loading = ref(true);
 const showSearch = ref(true);
 const total = ref(0);
+const showVarietyDialog = ref(false);
 const queryFormRef = ref<ElFormInstance>();
 const dataList = ref<any[]>([]);
 const initFormData = {
-
+    id: undefined,
+    newsType: 0,
+    variety: [],
 };
 const data = reactive<any>({
     form: { ...initFormData },
@@ -169,7 +182,36 @@ const unpublishNews = async (row) => {
     }
 };
 
+/** 编辑新闻 */
+const edit = debounce(async () => {
+    const res = await editNewsApi(form.value);
+    if (res && res.code === 200) {
+        showVarietyDialog.value = false;
+        ElMessage.success('编辑成功');
+        getList();
+    }
+}, 500);
+
+const varietyOptions = ref([]);
+
+const fetchVarietyOptions = async () => {
+    const res = await getMedicineList({});
+    if (res && res.code === 200) {
+        varietyOptions.value = res.data.map(item => ({
+            label: item.varietyName,
+            value: item.id
+        }));
+    }
+};
+
+const bindVariety = async (row) => {
+    form.value.id = row.id;
+    form.value.variety = row.variety;
+    showVarietyDialog.value = true;
+};
+
 onMounted(() => {
     getList();
+    fetchVarietyOptions();
 });
 </script>

+ 119 - 0
src/views/dgtmedicine/news/medicinenews/noticeAdd.vue

@@ -0,0 +1,119 @@
+<template>
+    <div class="p-3">
+        <div class="bg-fff flex1 ov-hd d-flex flex-cln">
+            <div class="d-flex a-c pd-16 border-bottom">
+                <div class="f-s-20 c-333 f-w-7 mr-10">新增公告</div>
+                <el-button @click="router.go(-1)" type="primary" text>
+                    <el-icon>
+                        <Back />
+                    </el-icon>
+                    返回上一级
+                </el-button>
+            </div>
+            <div class="flex1 over-auto">
+                <el-form ref="formRef" label-width="auto" label-position="top" :model="form" :rules="rules" :disabled="disable">
+                    <div class="pd-16 border-bottom">
+                        <el-row :gutter="90">
+                            <el-col :span="8">
+                                <el-form-item label="公告标题:" prop="newsTitle">
+                                    <el-input v-model="form.newsTitle" clearable placeholder="请输入标题"></el-input>
+                                </el-form-item>
+                            </el-col>
+                            <el-col :span="8">
+                                <el-form-item label="发布时间:" prop="publishTime">
+                                    <el-date-picker v-model="form.publishTime" type="datetime" placeholder="选择日期时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" :disabled="disable"></el-date-picker>
+                                </el-form-item>
+                            </el-col>
+                        </el-row>
+                        <el-row :gutter="90">
+                            <el-col :span="8">
+                                <el-form-item label="来源:" prop="newsOrigin">
+                                    <el-input v-model="form.newsOrigin" clearable placeholder="请输入标题"></el-input>
+                                </el-form-item>
+                            </el-col>
+                            <el-col :span="8">
+                                <el-form-item label="封面图" prop="newsImg">
+                                    <imageUpload v-model="form.newsImg" :limit="1" isString :isShowTip="false"></imageUpload>
+                                </el-form-item>
+                            </el-col>
+                        </el-row>
+                        <el-row>
+                            <el-col :span="24">
+                                <el-form-item label="公告内容" prop="newsContent">
+                                    <Editor v-model="form.newsContent" placeholder="请输入内容" :readOnly="disable"></Editor>
+                                </el-form-item>
+                            </el-col>
+                        </el-row>
+                    </div>
+                </el-form>
+            </div>
+            <div class="d-flex a-c j-c pd-16">
+                <el-button @click="router.go(-1)">取消</el-button>
+                <el-button @click="save" color="#0079fe" :disabled="disable">暂存</el-button>
+                <el-button @click="submitGround" type="warning" :disabled="disable">立即上架</el-button>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup name="MedicineNews-add" lang="ts">
+import { ref, reactive, onMounted } from 'vue';
+import { debounce } from 'lodash';
+import { addNews, editNews, publishNews, getNewsInfo } from '@/api/dgtmedicine/news';
+import { useRouter } from 'vue-router';
+import { getMedicineList } from '@/api/dgtmedicine/variety';
+const router = useRouter();
+const form = ref({
+    id: undefined,
+    newsTitle: '',
+    newsContent: '',
+    newsImg: '',
+    publishTime: '',
+    newsOrigin: '',
+    newsType: '1',
+
+});
+const rules = reactive({
+    newsTitle: [
+        { required: true, message: '请输入标题', trigger: 'blur' }
+    ],
+    content: [
+        { required: true, message: '请输入内容', trigger: 'blur' }
+    ]
+});
+const formRef = ref();
+const varietyOptions = ref([]);
+
+
+const save = debounce(async () => {
+    await formRef.value.validate();
+    const res = form.value.id ? await editNews(form.value) : await addNews(form.value);
+    if (res && res.code === 200) {
+        router.go(-1);
+    }
+}, 500);
+
+const submitGround = debounce(async () => {
+    await formRef.value.validate();
+    const res = form.value.id ? await editNews(form.value) : await addNews(form.value);
+    if (res && res.code === 200) {
+        await publishNews(res.data.id);
+        router.go(-1);
+    }
+}, 500);
+const fetchDetail = async (id) => {
+    const res = await getNewsInfo(id);
+    if (res && res.code === 200) {
+        form.value = res.data;
+    }
+};
+const disable = ref(false);
+onMounted(() => {
+    const id = router.currentRoute.value.query.id;
+    disable.value = router.currentRoute.value.query.disable == '1'
+    if (id) {
+        // 编辑
+        fetchDetail(id);
+    }
+});
+</script>

+ 171 - 0
src/views/dgtmedicine/news/medicinenews/noticeIndex.vue

@@ -0,0 +1,171 @@
+<template>
+    <div class="p-3">
+        <div class="bg-fff flex1 ov-hd d-flex flex-cln" v-show="showSearch">
+            <div class="pd-16 border-bottom">
+                <div class="f-s-20 c-333 f-w-7 mb-10">公告发布</div>
+                <div class="d-flex">
+                    <div class="mr-40">
+                        <el-button @click="router.push({ path: 'noticeAdd' })" type="primary">新增公告</el-button>
+                    </div>
+                    <div class="flex1 ov-hd d-flex j-ed">
+                        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="auto">
+                            <el-form-item label="标题" prop="newsTitle">
+                                <el-input v-model="queryParams.newsTitle" placeholder="请输入标题" clearable style="width: 180px" @keyup.enter="handleQuery" />
+                            </el-form-item>
+                            <el-form-item label="发布时间" prop="dateRange">
+                                <div class="d-flex" style="width: 180px">
+                                    <DateRange v-model="queryParams.dateRange" v-model:start-date="queryParams.startDate" v-model:end-date="queryParams.endDate"></DateRange>
+                                </div>
+                            </el-form-item>
+                            <el-form-item label="状态" prop="newsStatus">
+                                <el-select style="width: 140px" v-model="queryParams.newsStatus" clearable placeholder="请选择状态">
+                                    <el-option v-for="item in news_status" :key="item.value" :label="item.label" :value="item.value" />
+                                </el-select>
+                            </el-form-item>
+                            <el-form-item>
+                                <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+                                <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+                            </el-form-item>
+                        </el-form>
+                    </div>
+                </div>
+            </div>
+
+            <div class="d-flex flex1 ov-hd flex-cln pd-16">
+                <div class="pd-8"></div>
+                <div class="flex1 ov-hd">
+                    <vxe-table :loading="loading" border :data="dataList" min-height="0" max-height="100%">
+                        <vxe-column title="序号" align="center" type="seq" width="60" />
+                        <vxe-column title="公告标题" align="center" field="newsTitle" :formatter="colNoData" width="400" />
+                        <vxe-column title="发布时间" align="center" field="publishTime" :formatter="colNoData" />
+                        <vxe-column title="来源" align="center" field="newsOrigin" :formatter="colNoData" />
+                        <!-- <vxe-column title="浏览量" align="center" field="publishTime" :formatter="colNoData" /> -->
+                        <vxe-column title="操作人" align="center" field="createByName" :formatter="colNoData" />
+                        <vxe-column title="操作时间" align="center" field="createTime" :formatter="colNoData" />
+                        <vxe-column title="状态" align="center" field="newsStatus">
+                            <template #default="{ row }">
+                                <dict-tag :options="news_status" :value="row.newsStatus" />
+                            </template>
+                        </vxe-column>
+                        <vxe-column title="操作" width="250" align="center" fixed="right">
+                            <template #default="{ row }">
+                                <el-button type="text" size="small" @click="row.newsStatus === '1' ? unpublishNews(row) : publishNews(row)">
+                                    {{ row.newsStatus === '1' ? '下架' : '上架' }}
+                                </el-button>
+                                <el-button type="text" size="small" @click="editNews(row)">编辑</el-button>
+                                <el-button type="text" size="small" @click="viewNewsDetail(row)">详情</el-button>
+                                <el-button type="text" size="small" @click="deleteNews(row)">删除</el-button>
+                            </template>
+                        </vxe-column>
+                    </vxe-table>
+                </div>
+                <pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup name="MedicineNews" lang="ts">
+import { colNoData } from '@/utils/noData';
+import { publishNews as publishNewsApi, unpublishNews as unpublishNewsApi, removeNews, fetchNewsList } from '@/api/dgtmedicine/news';
+import { DateRange } from '@/views/models/index';
+const router = useRouter();
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { news_status } = toRefs<any>(proxy?.useDict('news_status'));
+const loading = ref(true);
+const showSearch = ref(true);
+const total = ref(0);
+const queryFormRef = ref<ElFormInstance>();
+const dataList = ref<any[]>([]);
+const initFormData = {
+
+};
+const data = reactive<any>({
+    form: { ...initFormData },
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        newsType: '1',
+        newsTitle: '',
+        newsStatus: ''
+    },
+    rules: {}
+});
+
+const { queryParams, form } = toRefs(data);
+/** 查询会员信息列表 */
+const getList = async () => {
+    loading.value = true;
+    const res = await fetchNewsList(queryParams.value);
+    dataList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
+};
+
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+    queryParams.value.pageNum = 1;
+    getList();
+};
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+    queryFormRef.value?.resetFields();
+    handleQuery();
+};
+
+/** 编辑新闻 */
+const editNews = (row) => {
+    router.push({ path: `noticeAdd`, query: { id: row.id ,title:'新增公告'} });
+};
+
+/** 删除新闻 */
+const deleteNews = async (row) => {
+    ElMessageBox.confirm(`确认要删除 "${row.newsTitle}" 新闻吗?`, '删除提示', {
+        confirmButtonText: '确认',
+        cancelButtonText: '取消',
+        type: 'warning',
+    }).then(async () => {
+        const res = await removeNews([row.id]);
+        if (res) {
+            ElMessage.success('删除成功');
+            getList();
+        }
+    });
+};
+
+/** 查看新闻详情 */
+const viewNewsDetail = (row) => {
+    router.push({ path: `noticeAdd`, query: { id: row.id, disable: '1' ,title:'公告详情'} });
+};
+/** 上架新闻 */
+const publishNews = async (row) => {
+    try {
+        const res = await publishNewsApi(row.id); // Replace with your API call
+        if (res) {
+            ElMessage.success('新闻已上架');
+            getList();
+        }
+    } catch (error) {
+        ElMessage.error('上架失败');
+    }
+};
+
+/** 下架新闻 */
+const unpublishNews = async (row) => {
+    try {
+        const res = await unpublishNewsApi(row.id); // Replace with your API call
+        if (res) {
+            ElMessage.success('新闻已下架');
+            getList();
+        }
+    } catch (error) {
+        ElMessage.error('下架失败');
+    }
+};
+
+onMounted(() => {
+    getList();
+});
+</script>