ProductLines.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. <template>
  2. <div>
  3. <crumbs title="产品申请列表" style="min-width: 1085px">
  4. <el-form :inline="true" class="demo-form-inline">
  5. <el-form-item label="申请时间:">
  6. <el-date-picker v-model="filter.time" size="mini" value-format="yyyy-MM-dd HH:mm:ss" :default-time="['00:00:01', '23:59:59']"
  7. type="daterange"
  8. start-placeholder="开始日期"
  9. end-placeholder="结束日期"></el-date-picker>
  10. </el-form-item>
  11. <el-form-item label="订单号:">
  12. <el-input size="mini" v-model="filter.orderNum" placeholder="订单号" clearable></el-input>
  13. </el-form-item>
  14. <el-form-item label="机构名称:">
  15. <el-input size="mini" v-model="filter.orgName" placeholder="机构名称" clearable></el-input>
  16. </el-select>
  17. </el-form-item>
  18. <el-form-item label="申请状态:">
  19. <el-select size="mini" v-model="filter.status" placeholder="申请状态" clearable>
  20. <el-option v-for="item in status" :label="item.name" :value="item.key"></el-option>
  21. </el-select>
  22. </el-form-item>
  23. <el-form-item>
  24. <el-button size="mini" @click="filterDatas">确认</el-button>
  25. <el-button size="mini" type="primary" @click="exportProductLines">导出</el-button>
  26. </el-form-item>
  27. </el-form>
  28. </crumbs>
  29. <div class="contents">
  30. <el-table :data="list"
  31. border
  32. @expand-change="showPickup"
  33. :row-class-name="proLineRow"
  34. width="100%"
  35. class="pro-line-table">
  36. <el-table-column
  37. type="index"
  38. :index="indexMethod"
  39. label="编号"
  40. width="60">
  41. </el-table-column>
  42. <el-table-column
  43. prop="time"
  44. label="申请时间"
  45. :show-overflow-tooltip="true">
  46. </el-table-column>
  47. <el-table-column
  48. prop="num"
  49. label="订单号"
  50. :show-overflow-tooltip="true">
  51. </el-table-column>
  52. <el-table-column
  53. prop="orgName"
  54. label="申请机构" width="100">
  55. </el-table-column>
  56. <el-table-column
  57. prop="linkman"
  58. label="申请人" width="100">
  59. </el-table-column>
  60. <el-table-column
  61. prop="username"
  62. label="手机号">
  63. </el-table-column>
  64. <el-table-column
  65. prop="email"
  66. label="邮箱"
  67. :show-overflow-tooltip="true">
  68. </el-table-column>
  69. <el-table-column
  70. label="操作" width="120">
  71. <template slot-scope="scope">
  72. <span class="status-span" v-if="scope.row.auditStatus==0">不通过</span>
  73. <span class="status-span" v-if="scope.row.auditStatus==1">通过</span>
  74. <el-button v-if="scope.row.auditStatus==2" type="text" size="small">{{scope.row.isExpand?"收起":"待审核"}}</el-button>
  75. <span class="status-span" v-if="scope.row.auditStatus==3">部分通过</span>
  76. <el-button v-if="scope.row.auditStatus==4" type="text" size="small">{{scope.row.isExpand?"收起":"部分审核"}}</el-button>
  77. <el-button type="text" size="small" :disabled="scope.row.auditStatus==2||scope.row.auditStatus==4">{{scope.row.isExpand&&(scope.row.auditStatus!=2&&scope.row.auditStatus!=4)?"收起":"查看"}}</el-button>
  78. </template>
  79. </el-table-column>
  80. <el-table-column type="expand">
  81. <!---------详情展开内容------------>
  82. <template slot-scope="scope">
  83. <el-table :data="scope.row.orderDetial">
  84. <el-table-column label="编号"
  85. type="index"
  86. width="60"
  87. :index="indexMethod"></el-table-column>
  88. <el-table-column label="申请时间"
  89. prop="orderTime"
  90. :show-overflow-tooltip="true"></el-table-column>
  91. <el-table-column label="开通功能" prop="productName"></el-table-column>
  92. <el-table-column label="付款状态" prop="payStatusName"></el-table-column>
  93. <el-table-column label="审核状态" width="130">
  94. <template slot-scope="detail">
  95. <el-popover
  96. v-if="detail.row.auditStatus==2"
  97. placement="top-start"
  98. width="260"
  99. v-model="detail.row.visible"
  100. >
  101. <el-form label-position="top" :inline="true" >
  102. <span class="closeDate" @click="detail.row.visible = false">×</span>
  103. <el-form-item label="服务开始时间">
  104. <el-date-picker size="mini" type="date"
  105. value-format="yyyy-MM-dd"
  106. placeholder="选择开始时间"
  107. :picker-options="startPicker"
  108. v-model="detailParam.startTime"
  109. style="width: 100%;"></el-date-picker>
  110. </el-form-item>
  111. <el-form-item label="服务结束时间">
  112. <el-date-picker size="mini" type="date"
  113. value-format="yyyy-MM-dd"
  114. :picker-options="endPicker"
  115. placeholder="选择结束时间"
  116. v-model="detailParam.endTime"
  117. style="width: 100%;"></el-date-picker>
  118. </el-form-item>
  119. <div style="text-align: center">
  120. <el-button type="primary" size="mini" @click="handleAuthStatus(detail.row,1,scope.row)">确定</el-button>
  121. </div>
  122. </el-form>
  123. <el-button slot="reference" size="mini"> 通过</el-button>
  124. </el-popover>
  125. <span v-if="detail.row.auditStatus==2" style="margin:0 3px;">|</span>
  126. <el-popover
  127. v-if="detail.row.auditStatus==2"
  128. placement="bottom-start"
  129. width="380"
  130. v-model="detail.row.visible2"
  131. >
  132. <el-form>
  133. <span class="closeDate" @click="detail.row.visible2 = false">×</span>
  134. <h4>原因说明</h4>
  135. <el-form-item>
  136. <el-radio-group v-model="detailParam.rejectType" @change="detailParam.rejectReason = ''">
  137. <p v-for="(it,index) in reasons" style="margin: 10px 0;">
  138. <el-radio :label="it.key">{{it.name}}</el-radio>
  139. </p>
  140. </el-radio-group>
  141. </el-form-item>
  142. <el-form-item>
  143. <el-input v-model="detailParam.rejectReason" @focus="detailParam.rejectType=-1" type="textarea" placeholder="其他原因说明"></el-input>
  144. </el-form-item>
  145. <el-form-item>
  146. <el-button type="primary" @click="handleAuthStatus(detail.row,0,scope.row)">完成</el-button>
  147. </el-form-item>
  148. </el-form>
  149. <el-button slot="reference" size="mini">不通过</el-button>
  150. </el-popover>
  151. <span class="status-span" v-if="detail.row.auditStatus==1">通过</span>
  152. <span class="status-span" v-if="detail.row.auditStatus==0">不通过</span>
  153. </template>
  154. </el-table-column>
  155. <el-table-column label="产品服务有效期" width="250">
  156. <template slot-scope="scope">
  157. {{scope.row.startTime&&scope.row.startTime.substr(0,10)}}~{{scope.row.endTime&&scope.row.endTime.substr(0,10)}}
  158. </template>
  159. </el-table-column>
  160. <el-table-column label="不通过说明" width="180">
  161. <template slot-scope="scope">
  162. {{scope.row.rejectReason||scope.row.rejectTypeName}}
  163. </template>
  164. </el-table-column>
  165. </el-table>
  166. </template>
  167. <!---------详情展开内容end------------>
  168. </el-table-column>
  169. </el-table>
  170. </div>
  171. <el-pagination v-if="total>pageSize"
  172. :current-page.sync="currentPage"
  173. @current-change="currentChange"
  174. background
  175. :page-size="pageSize"
  176. layout="total,prev, pager, next, jumper"
  177. :total="total">
  178. </el-pagination>
  179. </div>
  180. </template>
  181. <script>
  182. import api from '@api/admin.js';
  183. import utils from '@api/utils.js';
  184. export default {
  185. name: 'product-lines',
  186. data: function () {
  187. return {
  188. visible: false,
  189. visible2: false,
  190. list: [],
  191. status: [],
  192. cacheData: {},
  193. endPicker:{
  194. disabledDate:(current)=>{ //小于开始时间或今天之前不可选
  195. const today = new Date(new Date(new Date().toLocaleDateString()).getTime());
  196. return current<new Date(this.detailParam.startTime)||current<today;
  197. }
  198. },
  199. startPicker:{
  200. disabledDate:(current)=>{ //大于结束时间或今天之前不能选
  201. const today = new Date(new Date(new Date().toLocaleDateString()).getTime());
  202. return current > new Date(new Date(this.detailParam.endTime).getTime()-1000*60*60*24)||current<today;
  203. }
  204. },
  205. reasons:[],
  206. detailParam:{
  207. endTime:'',
  208. rejectReason:'',
  209. rejectType:-1,
  210. auditStatus:'',
  211. startTime:''
  212. },
  213. currentPage: 1,
  214. pageSize: 10,
  215. total: 0,
  216. filter: {
  217. orderNum: '',
  218. orgName: '',
  219. status: '',
  220. time:[]
  221. }
  222. }
  223. },
  224. created() {
  225. this.getDataList();
  226. const enums = JSON.parse(localStorage.getItem('productEnumsData'));
  227. this.reasons = enums&&enums.notPassEnum; //审核不通过原因枚举
  228. this.status = enums&&enums.auditStatusEnum; //申请状态枚举
  229. },
  230. methods: {
  231. showPickup(row){
  232. row.isExpand = !row.isExpand;
  233. },
  234. proLineRow(row){
  235. const status = row.row.auditStatus;
  236. if(status==2||status==4){ //查看
  237. return 'pro-line-auth';
  238. }else{ //待审核
  239. return 'pro-line-view';
  240. }
  241. },
  242. filterDatas(){
  243. this.currentPage = 1;
  244. this.getDataList();
  245. },
  246. getDataList() {
  247. const param = this.getFilterItems();
  248. api.getProductLines(param).then((res) => {
  249. if (res.data.code == '0') {
  250. const data = res.data.data;
  251. this.list = data.records.map((item) =>{
  252. let orderDetial = item.orderDetial.map((detail) => {
  253. return {...detail, visible: false, visible2: false}
  254. })
  255. return {...item, orderDetial}
  256. });
  257. this.cacheData[param.current] = data.records;
  258. this.total = data.total;
  259. }
  260. }).catch((error) => {
  261. console.log(error);
  262. });
  263. },
  264. clearStatus(){
  265. this.detailParam.rejectReason = '';
  266. this.detailParam.rejectType = -1;
  267. this.detailParam.endTime = '';
  268. this.detailParam.startTime = '';
  269. },
  270. handleAuthStatus(row,status,parent){
  271. this.detailParam.id = row.id;
  272. this.detailParam.auditStatus = status;
  273. if(status==1){ //通过参数
  274. if(!this.detailParam.endTime||!this.detailParam.startTime){
  275. this.$message({
  276. showClose: true,
  277. message:'请填写服务时间',
  278. type:'warning'
  279. });
  280. return;
  281. }
  282. this.detailParam.rejectReason = undefined;
  283. this.detailParam.rejectType = undefined;
  284. }else{ //不通过参数
  285. if(this.detailParam.rejectType===-1&&this.detailParam.rejectReason===''){
  286. this.$message({
  287. showClose: true,
  288. message:'请选择/填写不通过原因',
  289. type:'warning'
  290. });
  291. return;
  292. }
  293. if(this.detailParam.rejectReason.length>100){
  294. this.$message({
  295. showClose: true,
  296. message:'不通过原因最多可输入100字',
  297. type:'warning'
  298. });
  299. return;
  300. }
  301. this.detailParam.startTime = undefined;
  302. this.detailParam.endTime = undefined;
  303. }
  304. api.auditProductStatus(this.detailParam).then((res)=>{
  305. if(res.data.code=='0'){
  306. row.auditStatus = this.detailParam.auditStatus; //通过后修改显示状态
  307. //判断详情中审核状态-修改父级审核状态
  308. const details = parent.orderDetial;
  309. const unAuth = details.filter((it)=>{
  310. return it.auditStatus ==2;
  311. });
  312. const pass = details.filter((it)=>{
  313. return it.auditStatus ==1;
  314. });
  315. const unPass = details.filter((it)=>{
  316. return it.auditStatus ==0;
  317. });
  318. if(unAuth.length>0){ //部分审核
  319. parent.auditStatus = 4;
  320. }else if(pass.length==details.length){ //全部通过
  321. parent.auditStatus = 1;
  322. }else if(unPass.length==details.length){ //全部不通过
  323. parent.auditStatus = 0;
  324. }else{ //部分通过
  325. parent.auditStatus = 3;
  326. }
  327. if(status==1){ //通过成功
  328. row.startTime = this.detailParam.startTime;
  329. row.endTime = this.detailParam.endTime;
  330. row.payStatusName = '已付款';
  331. }else{ //不通过成功
  332. if(this.detailParam.rejectReason===''){
  333. const reason = this.reasons.filter((it)=>{
  334. return it.key === this.detailParam.rejectType;
  335. });
  336. row.rejectTypeName = reason[0]&&reason[0].name;
  337. }else{
  338. row.rejectTypeName = this.detailParam.rejectReason;console.log(this.detailParam.rejectReason)
  339. }
  340. }
  341. this.$message({
  342. showClose: true,
  343. message:'操作成功',
  344. type:'success'
  345. });
  346. //this.getDataList(); //操作成功刷新列表
  347. }else{
  348. this.$message({
  349. showClose: true,
  350. message:res.data.msg,
  351. type:'warning'
  352. });
  353. this.getDataList();//操作成功刷新列表
  354. }
  355. this.clearStatus();
  356. });
  357. },/*
  358. getDetailTable(row){
  359. const param = {
  360. orderNum: row.num
  361. };
  362. api.proDetails(param).then((res)=>{
  363. if(res.data.code=='0'){
  364. this.detail = res.data.data; //对象被修改不会更新vue数据,所以单独用一个变量来引起变化
  365. this.detailData[row.num] = res.data.data;
  366. }else{
  367. this.$message({
  368. showClose: true,
  369. message: res.data.msg,
  370. type: 'warning'
  371. });
  372. }
  373. }).catch((error)=>{
  374. this.$message({
  375. showClose: true,
  376. message: error,
  377. type: 'warning'
  378. });
  379. });
  380. },*/
  381. getFilterItems() {
  382. const time = this.filter.time;
  383. const startTime = time&&time[0]||undefined;
  384. const endTime = time&&time[1]||undefined;
  385. const param = {
  386. startTime,
  387. endTime,
  388. num: this.filter.orderNum,
  389. orgName: this.filter.orgName,
  390. auditStatus: this.filter.status,
  391. current: this.currentPage,
  392. size: this.pageSize
  393. };
  394. return param;
  395. },
  396. indexMethod(index) {
  397. return ((this.currentPage - 1) * this.pageSize) + index + 1;
  398. },
  399. currentChange(next) {
  400. this.currentPage = next;
  401. if (this.cacheData[next]) { //如果已请求过该页数据,则使用缓存不重复请求
  402. this.list = this.cacheData[next];
  403. } else {
  404. this.getDataList();
  405. }
  406. },
  407. exportProductLines() {
  408. const canExport = utils.exportCondition(this.filter.time)
  409. if(typeof canExport == 'string'){
  410. this.$message({
  411. showClose: true,
  412. message:canExport,
  413. type:'warning'
  414. });
  415. return;
  416. }
  417. const param = this.getFilterItems();
  418. api.exportProductLines(param).then((res) => {
  419. if (res.data.code = '0') {
  420. utils.downloadExportedData(res.data,'产品申请列表.xls');
  421. this.$message({showClose: true,message: "导出成功", type: 'success'});
  422. } else {
  423. this.$message({
  424. showClose: true,
  425. message: res.data.msg,
  426. type: 'warning'
  427. });
  428. }
  429. }).catch((error) => {
  430. this.$message({
  431. showClose: true,
  432. message: "服务器正忙...",
  433. type: 'warning'
  434. });
  435. });
  436. }
  437. }
  438. }
  439. </script>
  440. <style lang="less" scoped>
  441. @import "../../less/admin.less";
  442. .status-span{
  443. font-size: 14px;
  444. margin-right:10px;
  445. color: #aaa;
  446. }
  447. .closeDate {
  448. position: absolute;
  449. top: 0px;
  450. right: 7px;
  451. cursor: pointer;
  452. font-size: 20px;
  453. }
  454. </style>