watchlogReport.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. <template>
  2. <div class="app-container">
  3. <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="90px">
  4. <!-- <el-radio-group v-model="queryParams.dimension" @change="handleDimensionChange">-->
  5. <!-- <el-radio-button label="user">用户维度</el-radio-button>-->
  6. <!-- <el-radio-button label="sales">销售维度</el-radio-button>-->
  7. <!-- <el-radio-button label="company">公司维度</el-radio-button>-->
  8. <!-- </el-radio-group>-->
  9. <!-- <el-form-item label="公司名" prop="companyId">-->
  10. <!-- <el-select filterable v-model="queryParams.companyId" placeholder="请选择公司名"-->
  11. <!-- clearable size="small">-->
  12. <!-- <el-option-->
  13. <!-- v-for="item in companys"-->
  14. <!-- :key="item.companyId"-->
  15. <!-- :label="item.companyName"-->
  16. <!-- :value="item.companyId"-->
  17. <!-- />-->
  18. <!-- </el-select>-->
  19. <!-- </el-form-item>-->
  20. <el-form-item label="所属部门" prop="deptId">
  21. <treeselect style="width:205.4px" v-model="queryParams.deptId" :options="deptTreeOptions" :show-count="true" placeholder="请选择所属部门" />
  22. </el-form-item>
  23. <el-form-item label="项目" prop="project">
  24. <el-select filterable v-model="queryParams.project" placeholder="请选择项目"
  25. clearable size="small">
  26. <el-option
  27. v-for="item in projectList"
  28. :key="item.dictValue"
  29. :label="item.dictLabel"
  30. :value="item.dictValue"
  31. />
  32. </el-select>
  33. </el-form-item>
  34. <el-form-item label="训练营" prop="trainingCampId">
  35. <el-select filterable v-model="queryParams.trainingCampId" placeholder="请选择训练营"
  36. clearable size="small" @change="handleCampChange">
  37. <el-option
  38. v-for="item in camps"
  39. :key="item.dictValue"
  40. :label="item.dictLabel"
  41. :value="item.dictValue"
  42. />
  43. </el-select>
  44. </el-form-item>
  45. <el-form-item>
  46. <treeselect style="width: 220px" v-model="queryParams.periodId" :options="deptOptions"
  47. clearable :show-count="true" placeholder="请选择归属营期" value-consists-of="LEAF_PRIORITY"
  48. :normalizer="normalizer" />
  49. </el-form-item>
  50. <el-form-item>
  51. <el-form-item label="看课时间" prop="createTime">
  52. <el-date-picker v-model="createTime" size="small" style="width: 220px" value-format="yyyy-MM-dd"
  53. type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
  54. @change="xdChange"></el-date-picker>
  55. </el-form-item>
  56. <el-form-item label="下单时间" prop="createTime">
  57. <el-date-picker v-model="orderTime" size="small" style="width: 220px" value-format="yyyy-MM-dd"
  58. type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
  59. @change="ydChange"></el-date-picker>
  60. </el-form-item>
  61. </el-form-item>
  62. <el-form-item label="会员ID" prop="userId">
  63. <el-input v-model="queryParams.userId" placeholder="请输入会员ID" clearable size="small" />
  64. </el-form-item>
  65. <el-form-item label="会员手机号" prop="userPhone">
  66. <el-input v-model="queryParams.userPhone" placeholder="请输入会员手机号" clearable size="small" />
  67. </el-form-item>
  68. <el-form-item label="会员昵称" prop="nickName">
  69. <el-input v-model="queryParams.nickName" placeholder="请输入会员昵称" clearable size="small" />
  70. </el-form-item>
  71. <el-form-item>
  72. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  73. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  74. </el-form-item>
  75. </el-form>
  76. <el-table v-loading="loading" border :data="packageList">
  77. <el-table-column label="会员id" align="center" prop="userId" />
  78. <el-table-column label="会员昵称" align="center" prop="nickName" />
  79. <el-table-column label="所属销售" align="center" prop="salesName" />
  80. <el-table-column label="所属销售部门" align="center" prop="salesDept"/>
  81. <el-table-column label="所属销售公司" align="center" prop="salesCompany"/>
  82. <el-table-column label="训练营" align="center" prop="trainingCampName"/>
  83. <el-table-column label="营期" align="center" prop="periodName"/>
  84. <el-table-column label="小节名称" align="center" prop="videoTitle" />
  85. <el-table-column label="看课状态" align="center" prop="watchStatus" />
  86. <el-table-column label="播放时长" align="center" prop="duration" />
  87. <el-table-column label="看课时间" align="center" prop="courseTime" />
  88. <el-table-column label="完课时间" align="center" prop="finishTime" />
  89. <el-table-column label="答题状态" align="center" prop="answerStatus" />
  90. <el-table-column label="红包金额" align="center" prop="redPacketAmount" />
  91. <el-table-column label="历史疗法订单数" align="center" prop="historyOrderCount" />
  92. </el-table>
  93. <!-- <div class="total-summary">-->
  94. <!-- <span class="total-title">总计:</span>-->
  95. <!-- <span class="total-item">完课数: {{ calculatedTotalData.finishedCount }}</span>-->
  96. <!-- <span class="total-item">未完课: {{ calculatedTotalData.unfinishedCount }}</span>-->
  97. <!-- <span class="total-item">完课率: {{ calculatedTotalData.completionRate }}</span>-->
  98. <!-- <span class="total-item">未看数: {{ calculatedTotalData.notWatchedCount }}</span>-->
  99. <!-- <span class="total-item">未答题人数: {{ calculatedTotalData.notAnsweredCount }}</span>-->
  100. <!-- <span class="total-item">红包金额: {{ calculatedTotalData.redPacketAmount }}</span>-->
  101. <!-- <span class="total-item">历史疗法订单数: {{ calculatedTotalData.historyOrderCount }}</span>-->
  102. <!-- </div>-->
  103. <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
  104. @pagination="getList" />
  105. <!-- 添加或修改套餐包对话框 -->
  106. <!-- <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
  107. <el-form ref="form" :model="form" :rules="rules" label-width="110px">
  108. <el-form-item label="套餐包名称" prop="packageName">
  109. <el-input v-model="form.packageName" placeholder="请输入套餐包名称" />
  110. </el-form-item>
  111. <el-form-item label="排序号" prop="sort">
  112. <el-input-number v-model="form.sort" :min="0" label="排序号"></el-input-number>
  113. </el-form-item>
  114. <el-form-item label="状态">
  115. <el-radio-group v-model="form.status">
  116. <el-radio
  117. v-for="dict in statusOptions"
  118. :key="dict.dictValue"
  119. :label="parseInt(dict.dictValue)"
  120. >{{dict.dictLabel}}</el-radio>
  121. </el-radio-group>
  122. </el-form-item>
  123. <el-form-item label="价格配置" prop="priceJson">
  124. <el-table :data="priceJson" :cell-style="{ textAlign: 'center' }" :header-cell-style="{textAlign: 'center'}" >
  125. <el-table-column label="子套餐标题" prop="title" width="150px">
  126. <template slot-scope="scope">
  127. <el-input v-model="scope.row.title" ></el-input>
  128. </template>
  129. </el-table-column>
  130. <el-table-column label="签约时长/日" prop="duration" width="150px">
  131. <template slot-scope="scope">
  132. <el-input-number v-model="scope.row.duration" controls-position="right" :min="0" size="small"></el-input-number>
  133. </template>
  134. </el-table-column>
  135. <el-table-column label="价格/元" prop="price" width="150px">
  136. <template slot-scope="scope">
  137. <el-input-number v-model="scope.row.price" controls-position="right" :min="0" size="small"></el-input-number>
  138. </template>
  139. </el-table-column>
  140. <el-table-column label="状态" prop="status">
  141. <template slot-scope="scope">
  142. <el-switch v-model="scope.row.status" active-color="#13ce66" inactive-color="#ff4949" ></el-switch>
  143. </template>
  144. </el-table-column>
  145. <el-table-column label="操作">
  146. <template slot-scope="scope">
  147. <el-button @click="deleteRow(scope.$index)" size="mini" type="text" v-if="priceJson.length>1">删除</el-button>
  148. <el-button @click="addRow" size="mini" type="text" >新增</el-button>
  149. </template>
  150. </el-table-column>
  151. </el-table>
  152. </el-form-item>
  153. </el-form>
  154. <div slot="footer" class="dialog-footer">
  155. <el-button type="primary" @click="submitForm">确 定</el-button>
  156. <el-button @click="cancel">取 消</el-button>
  157. </div>
  158. </el-dialog> -->
  159. </div>
  160. </template>
  161. <script>
  162. import {
  163. listPackage,
  164. getPackage,
  165. delPackage,
  166. addPackage,
  167. updatePackage,
  168. exportPackage,
  169. userReport, watchLogReport
  170. } from "@/api/store/package";
  171. import { getAllFollowTempName } from "@/api/store/followTemp";
  172. import { allIcd } from "@/api/store/icd";
  173. import Editor from '@/components/Editor/wang.vue';
  174. import Material from '@/components/Material/index.vue';
  175. import Treeselect from "@riophae/vue-treeselect";
  176. import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  177. import { listStore,getCampList,getPeriodList} from "@/api/store/storeProduct";
  178. import { getAllCateList } from "@/api/store/packageCate";
  179. import { Loading } from 'element-ui';
  180. import {getCompanyList} from "@/api/company/company";
  181. import {selectDeptTree} from "@/api/company/companyDept";
  182. export default {
  183. name: "WatchlogReport",
  184. components: {Treeselect},
  185. watch: {
  186. imageArr: function (val) {
  187. this.form.imgUrl = val.join(',')
  188. },
  189. photoArr: function (val) {
  190. this.form.images = val.join(',')
  191. },
  192. // 监听公司选择变化,动态加载对应部门
  193. // 'queryParams.companyId': {
  194. // handler(newVal) {
  195. // this.queryParams.deptId = null; // 清空已选择的部门
  196. // const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}');
  197. // const companyId = newVal || userInfo.companyId;
  198. // if (companyId) {
  199. // this.getTreeselect(companyId); // 根据公司ID获取部门树
  200. // } else {
  201. // this.deptTreeOptions = []; // 如果没有选择公司,则清空部门选项
  202. // }
  203. // }
  204. // }
  205. },
  206. data() {
  207. return {
  208. normalizer: function(node) {
  209. return {
  210. id: node.id || node.dictValue,
  211. label: node.label || node.dictLabel,
  212. children: node.children
  213. }
  214. },
  215. columnConfig: {
  216. user: [
  217. { prop: 'userId', label: '会员id', width: 120 },
  218. { prop: 'nickName', label: '用户昵称', width: 120 },
  219. { prop: 'salesName', label: '所属销售', width: 120 },
  220. { prop: 'salesDept', label: '所属销售部门', width: 120, condition: () => this.showDeptNameColumn },
  221. { prop: 'salesCompany', label: '所属销售公司', width: 120 },
  222. { prop: 'trainingCampName', label: '训练营', width: 150 },
  223. { prop: 'periodName', label: '营期', width: 150 },
  224. { prop: 'videoTitle', label: '小节名称', width: 100 },
  225. { prop: 'watchStatus', label: '看课状态', width: 100 },
  226. { prop: 'duration', label: '播放时长', width: 120 },
  227. { prop: 'courseTime', label: '看课时间', width: 100 },
  228. { prop: 'finishTime', label: '完课时间', width: 100 },
  229. { prop: 'answerStatus', label: '答题状态', width: 100 },
  230. { prop: 'redPacketAmount', label: '红包金额', width: 120 },
  231. { prop: 'historyOrderCount', label: '历史疗法订单数', width: 120 }
  232. ],
  233. sales: [
  234. { prop: 'salesName', label: '销售', width: 120 },
  235. { prop: 'userCount', label: '会员数', width: 120 },
  236. { prop: 'onlineUserCount', label: '当前线上会员数', width: 120 },
  237. { prop: 'salesDept', label: '所属销售部门', width: 100, sortable: true },
  238. { prop: 'salesCompany', label: '所属销售公司', width: 120, sortable: true },
  239. { prop: 'trainingCampName', label: '训练营', width: 100, sortable: true },
  240. { prop: 'periodName', label: '营期', width: 100, sortable: true },
  241. { prop: 'videoTitle', label: '课程小节', width: 100, sortable: true },
  242. { prop: 'finishedCount', label: '完课数', width: 100, sortable: true },
  243. { prop: 'unfinishedCount', label: '未完课', width: 120, sortable: true },
  244. { prop: 'completionRate', label: '完课率', width: 100, sortable: true },
  245. { prop: 'courseTime', label: '发课时间', width: 100, sortable: true },
  246. { prop: 'notWatchedCount', label: '未看数', width: 100, sortable: true },
  247. { prop: 'notAnsweredCount', label: '未答题人数', width: 100, sortable: true },
  248. { prop: 'redPacketAmount', label: '红包金额', width: 120 },
  249. { prop: 'historyOrderCount', label: '历史疗法订单数', width: 120 }
  250. ],
  251. company: [
  252. { prop: 'salesDept', label: '销售部门', width: 120 },
  253. { prop: 'salesCount', label: '销售数', width: 120 },
  254. { prop: 'userCount', label: '会员数', width: 120 },
  255. { prop: 'onlineUserCount', label: '当前会员上线数', width: 100, sortable: true },
  256. { prop: 'salesCompany', label: '所属销售公司', width: 100, sortable: true },
  257. { prop: 'trainingCampName', label: '训练营', width: 120, sortable: true },
  258. { prop: 'periodName', label: '营期', width: 100, sortable: true },
  259. { prop: 'videoTitle', label: '课程小节', width: 100, sortable: true },
  260. { prop: 'finishedCount', label: '完课数', width: 100, sortable: true },
  261. { prop: 'unfinishedCount', label: '未完课', width: 120, sortable: true },
  262. { prop: 'completionRate', label: '完课率', width: 100, sortable: true },
  263. { prop: 'courseTime', label: '发课时间', width: 100, sortable: true },
  264. { prop: 'notWatchedCount', label: '未看数', width: 100, sortable: true },
  265. { prop: 'notAnsweredCount', label: '未答题人数', width: 100, sortable: true },
  266. { prop: 'redPacketAmount', label: '红包金额', width: 120 },
  267. { prop: 'historyOrderCount', label: '历史疗法订单数', width: 120 }
  268. ]
  269. },
  270. showDeptNameColumn: false,
  271. projectList: [],
  272. companys: [],
  273. camps: [],
  274. deptOptions : [],
  275. deptTreeOptions: [],
  276. uploadUrl: process.env.VUE_APP_BASE_API + "/common/uploadOSS",
  277. photoArr: [],
  278. productTypeOptions: [],
  279. storeId: null,
  280. storeOPtions: [],
  281. totalMoney: 0.00,
  282. drugOpen: false,
  283. checkList: ['1'],
  284. drugList: [],
  285. productJson: [],
  286. calculatedTotalData: {
  287. finishedCount: 0,
  288. unfinishedCount: 0,
  289. completionRate: 0,
  290. notWatchedCount: 0,
  291. notAnsweredCount: 0,
  292. redPacketAmount: 0,
  293. historyOrderCount: 0
  294. },
  295. describeJson: { usageMethod: "", forPeople: "", tabootPeople: "", use: "" },
  296. icdList: [],
  297. show: {
  298. open: false,
  299. },
  300. priceJson: [
  301. { title: "套餐1", duration: "0", price: "0", status: true },
  302. ],
  303. // 遮罩层
  304. loading: true,
  305. // 导出遮罩层
  306. exportLoading: false,
  307. // 选中数组
  308. ids: [],
  309. // 非单个禁用
  310. single: true,
  311. // 非多个禁用
  312. multiple: true,
  313. // 显示搜索条件
  314. showSearch: true,
  315. startTime : null,
  316. endTime : null,
  317. // 总条数
  318. total: 0,
  319. createTime: null,
  320. orderTime: null,
  321. // 套餐包表格数据
  322. packageList: [],
  323. // 弹出层标题
  324. title: "",
  325. // 是否显示弹出层
  326. open: false,
  327. // 状态字典
  328. tempOptions: [],
  329. statusOptions: [],
  330. payTypeOptions: [],
  331. orOptions: [],
  332. packageTypeOptions: [],
  333. diseaseTypeOptions: [],
  334. packageSubTypeOptions: [],
  335. solarTermOptions: [],
  336. // 查询参数
  337. queryParams: {
  338. pageNum: 1,
  339. pageSize: 10,
  340. packageName: null,
  341. sort: null,
  342. priceJson: null,
  343. status: null,
  344. isDel: null,
  345. companyId:null,
  346. project:null,
  347. trainingCampId:null,
  348. periodId:null,
  349. sTime: null,
  350. eTime: null,
  351. orderSTime: null,
  352. orderETime: null,
  353. deptId: null,
  354. dimension: 'user'
  355. },
  356. // 表单参数
  357. form: {},
  358. };
  359. },
  360. computed: {
  361. // // 计算属性:根据当前维度返回动态列
  362. // dynamicColumns() {
  363. // const dimension = this.queryParams.dimension || 'user';
  364. // return this.columnConfig[dimension] || this.columnConfig.user;
  365. // }
  366. },
  367. created() {
  368. console.log('公司id是否存在',this.$store.state.user.user)
  369. this.getTreeselect(this.$store.state.user.user.companyId);
  370. this.$nextTick(() => {
  371. console.log('handleDimensionChange 方法是否存在:', typeof this.handleDimensionChange);
  372. console.log('所有方法:', Object.keys(this));
  373. });
  374. // 在调用 getList 前确保 dimension 参数存在
  375. if (!this.queryParams.dimension) {
  376. this.queryParams.dimension = 'user';
  377. }
  378. getCampList().then(response => {
  379. this.camps = response.data.list
  380. if (this.camps != null && this.camps.length > 0) {
  381. this.companyId = this.camps[0].dictValue;
  382. }
  383. this.camps.push({companyId: "-1", companyName: "无"})
  384. });
  385. getCompanyList().then(response => {
  386. this.companys = response.data;
  387. if (this.companys != null && this.companys.length > 0) {
  388. this.companyId = this.companys[0].companyId;
  389. }
  390. this.companys.push({companyId: "-1", companyName: "无"})
  391. });
  392. this.getList();
  393. this.getDicts("sys_company_status").then(response => {
  394. this.statusOptions = response.data;
  395. });
  396. this.getDicts("sys_company_or").then(response => {
  397. this.isDelOptions = response.data;
  398. this.orOptions = response.data;
  399. });
  400. this.getDicts("sys_package_pay_type").then(response => {
  401. this.payTypeOptions = response.data;
  402. });
  403. this.getDicts("sys_product_type").then(response => {
  404. this.productTypeOptions = response.data;
  405. });
  406. this.getDicts("sys_package_type").then(response => {
  407. this.packageTypeOptions = response.data;
  408. });
  409. this.getDicts("sys_package_sub_type").then(response => {
  410. this.packageSubTypeOptions = response.data;
  411. });
  412. this.getDicts("sys_course_project").then(e => {
  413. this.projectList = e.data;
  414. })
  415. // this.getDicts("sys_prescribe_disease_type").then(response => {
  416. // this.diseaseTypeOptions = response.data;
  417. // });
  418. },
  419. methods: {
  420. handleDimensionChange: function(val) {
  421. console.log('维度切换到:', val);
  422. // 重置分页
  423. this.queryParams.pageNum = 1;
  424. // 重新获取数据
  425. this.getList();
  426. },
  427. calculateTotals() {
  428. // 重置总计数据
  429. this.calculatedTotalData = {
  430. finishedCount: 0,
  431. unfinishedCount: 0,
  432. completionRate: 0,
  433. notWatchedCount: 0,
  434. notAnsweredCount: 0,
  435. redPacketAmount: 0,
  436. historyOrderCount: 0
  437. };
  438. // 遍历当前页数据计算总和
  439. this.packageList.forEach(item => {
  440. this.calculatedTotalData.finishedCount += Number(item.finishedCount) || 0;
  441. this.calculatedTotalData.unfinishedCount += Number(item.unfinishedCount) || 0;
  442. this.calculatedTotalData.completionRate += Number(item.completionRate) || 0;
  443. this.calculatedTotalData.notWatchedCount += Number(item.notWatchedCount) || 0;
  444. this.calculatedTotalData.notAnsweredCount += Number(item.notAnsweredCount) || 0;
  445. this.calculatedTotalData.redPacketAmount += Number(item.redPacketAmount) || 0;
  446. this.calculatedTotalData.historyOrderCount += Number(item.historyOrderCount) || 0;
  447. });
  448. },
  449. getTreeselect(companyId) {
  450. const query = { companyId: companyId };
  451. selectDeptTree(query).then((response) => {
  452. this.deptTreeOptions = response.data;
  453. });
  454. },
  455. compute(){
  456. this.totalMoney=0;
  457. var that=this;
  458. this.drugList.forEach (function (value) {
  459. that.totalMoney += value.money;
  460. });
  461. that.totalMoney=that.totalMoney.toFixed(2);
  462. },
  463. // saveData(row) {
  464. // // 在这里可以进行数据保存操作,比如将数据提交到后端进行保存
  465. // console.log("保存数据", row);
  466. // },
  467. /** 查询套餐包列表 */
  468. getList() {
  469. this.loading = true;
  470. // 添加调试日志,确认参数
  471. console.log('请求参数:', this.queryParams);
  472. watchLogReport(this.queryParams).then(response => {
  473. this.packageList = response.rows;
  474. this.total = response.total;
  475. this.calculateTotals();
  476. this.loading = false;
  477. // 检查是否有数据且 deptName 字段有值,决定是否显示该列
  478. if (this.packageList && this.packageList.length > 0) {
  479. this.showDeptNameColumn = this.packageList.some(item => item.deptName);
  480. } else {
  481. this.showDeptNameColumn = false;
  482. }
  483. });
  484. },
  485. /** 训练营变更处理 */
  486. handleCampChange(val) {
  487. this.queryParams.trainingCampId = val;
  488. this.queryParams.periodId = null; // 清空已选择的营期
  489. if (val) {
  490. // 获取对应的营期数据
  491. this.getPeriodByCamp(val);
  492. } else {
  493. // 如果清空训练营,也清空营期选项
  494. this.deptOptions = [];
  495. }
  496. // 触发查询
  497. this.handleQuery();
  498. },
  499. /** 根据训练营获取营期数据 */
  500. getPeriodByCamp(campId) {
  501. const param = { campId: campId };
  502. getPeriodList(param).then((response) => {
  503. console.log('接口返回数据:', response);
  504. console.log('营期列表数据:', response.data.list);
  505. this.deptOptions = response.data.list || [];
  506. console.log('deptOptions 已赋值:', this.deptOptions);
  507. }).catch(error => {
  508. console.error('获取营期数据失败:', error);
  509. this.deptOptions = [];
  510. });
  511. },
  512. // 取消按钮
  513. cancel() {
  514. this.open = false;
  515. this.reset();
  516. },
  517. // 表单重置
  518. reset() {
  519. this.form = {
  520. packageId: null,
  521. packageName: null,
  522. sort: null,
  523. productJson: null,
  524. status: 0,
  525. createTime: null,
  526. orderTime: null,
  527. updateTime: null,
  528. isDel: null,
  529. payType: ["1"],
  530. isShow: "1",
  531. packageType: "1",
  532. num: null,
  533. price: null,
  534. sales: null,
  535. diseaseType: null,
  536. tags: null,
  537. packageSubType: "1",
  538. describeJson: null,
  539. productType: null,
  540. totalPrice: null,
  541. inquiryPrice: null,
  542. productPrice: null,
  543. cycle: null,
  544. duration: null,
  545. imgUrl: null,
  546. images: null,
  547. storeId: null,
  548. recipeType: null,
  549. counts: null,
  550. followNum: null,
  551. secondName: null,
  552. };
  553. this.photoArr = [];
  554. this.resetForm("form");
  555. },
  556. /** 搜索按钮操作 */
  557. handleQuery() {
  558. this.queryParams.pageNum = 1;
  559. this.getList();
  560. },
  561. /** 重置按钮操作 */
  562. resetQuery() {
  563. this.resetForm("queryForm");
  564. this.handleQuery();
  565. // 清空所有时间相关变量
  566. this.createTime = null;
  567. this.orderTime = null;
  568. this.startTime = null;
  569. this.endTime = null;
  570. this.queryParams.sTime = null;
  571. this.queryParams.orderSTime= null;
  572. this.queryParams.eTime = null;
  573. this.queryParams.orderETime= null;
  574. },
  575. xdChange() {
  576. if (this.createTime != null) {
  577. this.queryParams.sTime = this.createTime[0];
  578. this.queryParams.eTime = this.createTime[1];
  579. } else {
  580. this.queryParams.sTime = null;
  581. this.queryParams.eTime = null;
  582. }
  583. },
  584. ydChange() {
  585. if (this.orderTime != null) {
  586. this.queryParams.orderSTime = this.orderTime[0];
  587. this.queryParams.orderETime = this.orderTime[1];
  588. } else {
  589. this.queryParams.orderSTime = null;
  590. this.queryParams.orderETime = null;
  591. }
  592. }
  593. }
  594. };
  595. </script>
  596. <style>
  597. .icon-button {
  598. border-radius: 0;
  599. }
  600. .avatar-uploader .el-upload {
  601. border: 1px dashed #d9d9d9;
  602. border-radius: 6px;
  603. cursor: pointer;
  604. position: relative;
  605. overflow: hidden;
  606. }
  607. .avatar-uploader .el-upload:hover {
  608. border-color: #409EFF;
  609. }
  610. .avatar-uploader-icon {
  611. font-size: 28px;
  612. color: #8c939d;
  613. width: 150px;
  614. height: 150px;
  615. line-height: 150px !important;
  616. text-align: center;
  617. }
  618. .total-summary {
  619. margin-top: 15px;
  620. padding: 15px 20px;
  621. background: linear-gradient(135deg, #f5f7fa 0%, #e4e7f4 100%);
  622. border: 1px solid #dcdfe6;
  623. border-radius: 4px;
  624. box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  625. display: flex;
  626. flex-wrap: wrap;
  627. align-items: center;
  628. }
  629. .total-title {
  630. font-weight: bold;
  631. font-size: 16px;
  632. color: #303133;
  633. margin-right: 20px;
  634. flex-shrink: 0;
  635. }
  636. .total-item {
  637. margin-right: 25px;
  638. padding: 5px 10px;
  639. background: white;
  640. border-radius: 3px;
  641. box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
  642. display: inline-block;
  643. margin-bottom: 5px;
  644. font-size: 13px;
  645. color: #606266;
  646. }
  647. .total-item::before {
  648. content: "";
  649. display: inline-block;
  650. width: 3px;
  651. height: 3px;
  652. background: #409eff;
  653. border-radius: 50%;
  654. margin-right: 5px;
  655. vertical-align: middle;
  656. }
  657. /* 响应式处理 */
  658. @media (max-width: 768px) {
  659. .total-summary {
  660. flex-direction: column;
  661. align-items: flex-start;
  662. }
  663. .total-title {
  664. margin-bottom: 10px;
  665. }
  666. .total-item {
  667. margin-right: 10px;
  668. margin-bottom: 8px;
  669. }
  670. }
  671. </style>