index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. <template>
  2. <div class="page-container list-container">
  3. <!-- 功能按钮区 -->
  4. <div class="list-btns-container">
  5. <el-dropdown trigger="click">
  6. <el-button
  7. type="primary"
  8. size="small"
  9. v-if="
  10. hasPermi([
  11. 'business:customer:service:once:export',
  12. 'business:customer:service:once:transactor',
  13. ])
  14. "
  15. >
  16. 其它<el-icon class="el-icon--right"><arrow-down /></el-icon>
  17. </el-button>
  18. <template #dropdown>
  19. <el-dropdown-menu>
  20. <el-dropdown-item
  21. icon="Download"
  22. @click="handleExport"
  23. v-if="hasPermi(['business:customer:service:once:exportOnce'])"
  24. >
  25. 导出</el-dropdown-item
  26. >
  27. <el-dropdown-item
  28. icon="Operation"
  29. @click="setServiceHandler"
  30. v-if="hasPermi(['business:customer:service:once:transactor'])"
  31. >
  32. 设置执行人</el-dropdown-item
  33. >
  34. </el-dropdown-menu>
  35. </template>
  36. </el-dropdown>
  37. </div>
  38. <!-- 搜索区 -->
  39. <el-form
  40. class="list-search-container"
  41. size="small"
  42. :model="queryParams"
  43. ref="queryRef"
  44. :inline="true"
  45. label-width="68px"
  46. >
  47. <el-form-item label="客户名称:" prop="companyName">
  48. <el-input
  49. style="width: 150px"
  50. v-model="queryParams.companyName"
  51. placeholder="请输入客户名称"
  52. clearable
  53. @keyup.enter="handleQuery"
  54. />
  55. </el-form-item>
  56. <el-form-item label="状态:" prop="status">
  57. <el-select
  58. v-model.trim="queryParams.status"
  59. size="small"
  60. type="text"
  61. placeholder="状态"
  62. :clearable="true"
  63. style="width: 130px"
  64. @clear="clearStatus"
  65. >
  66. <el-option
  67. v-for="item in selectStatus"
  68. :key="item.value"
  69. :label="item.label"
  70. :value="item.value"
  71. />
  72. </el-select>
  73. </el-form-item>
  74. <el-form-item>
  75. <el-button type="primary" icon="Search" @click="handleQuery"
  76. >搜索</el-button
  77. >
  78. <el-button icon="Refresh" @click="resetQuery">重置</el-button>
  79. </el-form-item>
  80. </el-form>
  81. <!-- 列表区 -->
  82. <el-table
  83. v-loading="loading"
  84. :data="orderList"
  85. size="small"
  86. border
  87. height="100%"
  88. @selection-change="handleSelectionChange"
  89. >
  90. <el-table-column type="selection" width="55" align="center" />
  91. <!-- <el-table-column label="工单号" align="center" prop="workOrderNo" width="200" /> -->
  92. <el-table-column
  93. label="客户名称"
  94. align="center"
  95. prop="companyName"
  96. min-width="250"
  97. />
  98. <!-- <el-table-column
  99. label="税号"
  100. align="center"
  101. prop="socialCreditCode"
  102. min-width="180"
  103. /> -->
  104. <el-table-column
  105. label="服务内容"
  106. align="center"
  107. min-width="480"
  108. prop="remark"
  109. >
  110. <template #default="scope">
  111. <div>
  112. {{
  113. scope.row.noContract === 1? scope.row.remark: `${scope.row.taskTypeName}${scope.row.alterType ?`-${scope.row.alterType}` : ""}${scope.row.taskTypeDetailName? `-${scope.row.taskTypeDetailName}` : ""}`
  114. }}
  115. </div>
  116. </template>
  117. </el-table-column>
  118. <el-table-column
  119. label="说明"
  120. align="center"
  121. prop="explain"
  122. min-width="180"
  123. />
  124. <el-table-column label="状态" align="center" width="80">
  125. <template #default="scope">
  126. <div :style="getStatusStyle(scope.row)">
  127. {{ getStatusLabel(scope.row) }}
  128. <el-popover placement="top-start" width="250" trigger="hover">
  129. <div style="display: flex; flex-direction: row">
  130. <div
  131. v-for="item in selectStatus"
  132. :key="item.value"
  133. style="display: flex; flex-direction: row; margin-right: 10px"
  134. >
  135. <div
  136. :style="{
  137. backgroundColor: item.color,
  138. width: '14px',
  139. height: '14px',
  140. margin: 'auto',
  141. borderRadius: '50%',
  142. border: item.color === '#fff' ? '1px solid #ddd' : 'none',
  143. }"
  144. />
  145. <div
  146. style="
  147. display: inline-block;
  148. margin-left: 10px;
  149. line-height: 36px;
  150. font-size: 10px;
  151. "
  152. >
  153. {{ item.label }}
  154. </div>
  155. </div>
  156. </div>
  157. <template #reference>
  158. <span
  159. style="
  160. color: #fff;
  161. font-size: 12px;
  162. text-align: center;
  163. display: inline-block;
  164. line-height: 14px;
  165. width: 14px;
  166. height: 14px;
  167. background-color: #ccc;
  168. border-radius: 50%;
  169. "
  170. >?</span
  171. >
  172. </template>
  173. </el-popover>
  174. </div>
  175. </template>
  176. </el-table-column>
  177. <el-table-column label="操作" align="center" min-width="60">
  178. <template #default="scope">
  179. <el-button
  180. size="small"
  181. link
  182. type="primary"
  183. v-hasPermi="[
  184. 'business:customer:service:once:view',
  185. 'business:customer:service:once:edit',
  186. ]"
  187. @click="handleByRow(scope.row)"
  188. >查看</el-button
  189. >
  190. </template>
  191. </el-table-column>
  192. <el-table-column label="工单执行人" align="center" width="110">
  193. <template #default="scope">{{ getTransactor(scope.row) }}</template>
  194. </el-table-column>
  195. <el-table-column label="停止" align="center" prop="isStop" width="50">
  196. <template #default="scope">{{
  197. scope.row.isStop === 1 ? "是" : "否"
  198. }}</template>
  199. </el-table-column>
  200. </el-table>
  201. <!-- 分页 -->
  202. <pagination
  203. v-show="total > 0"
  204. :total="total"
  205. v-model:page="queryParams.pageNum"
  206. v-model:limit="queryParams.pageSize"
  207. @pagination="getList"
  208. />
  209. <service-form ref="serviceRef" :get-list="getList" />
  210. <form-dialog ref="formRef" :get-list="getList" />
  211. <view-dialog ref="viewRef" :get-list="getList" />
  212. </div>
  213. </template>
  214. <script setup name="Company">
  215. import { listOnce, exportOnce } from "@/api/business/crm/serviceWorkOrder";
  216. import auth from "@/plugins/auth";
  217. import useUserStore from "@/store/modules/user";
  218. const permissions = useUserStore().permissions;
  219. const all_permission = "*:*:*";
  220. import formDialog from "./form";
  221. import viewDialog from "./view";
  222. import serviceForm from "../serviceForm";
  223. import { ref, toRef } from "vue";
  224. // import workorderForm from "./form"
  225. const { proxy } = getCurrentInstance();
  226. /** 字典数组区 */
  227. /** 查询 对象 */
  228. const orderList = ref([]);
  229. const loading = ref(true);
  230. const ids = ref([]);
  231. const single = ref(true);
  232. const multiple = ref(true);
  233. const total = ref(0);
  234. const prev = ref([]);
  235. const data = reactive({
  236. selectStatus: [
  237. {
  238. label: "未开始",
  239. value: 0,
  240. color: "#888",
  241. },
  242. {
  243. label: "进行中",
  244. value: 1,
  245. color: "#FFB836",
  246. },
  247. {
  248. label: "已完成",
  249. value: 3,
  250. color: "#2FCB81",
  251. },
  252. ],
  253. });
  254. const formRef = ref(null);
  255. const viewRef = ref(null);
  256. const { selectStatus } = toRefs(data);
  257. const formOpen = ref(false);
  258. const form = ref({
  259. id: null,
  260. companyName: "",
  261. companyId: null,
  262. remark: "",
  263. type: 2,
  264. noContract: 1,
  265. });
  266. const emptyForm = {
  267. id: null,
  268. companyName: "",
  269. companyId: null,
  270. type: 2,
  271. remark: "",
  272. };
  273. const { contract_verify_status } = proxy.useDict("contract_verify_status");
  274. const { contract_status } = proxy.useDict("contract_status");
  275. /** 查询对象 */
  276. const queryParams = ref({
  277. pageNum: 1,
  278. pageSize: 20,
  279. companyName: "",
  280. orderByColumn: "create_time",
  281. type: 2,
  282. });
  283. const editStatus = {
  284. startMonth: false,
  285. };
  286. /*********************** 方法区 ****************************/
  287. /** 查询company列表 */
  288. function getList() {
  289. loading.value = true;
  290. listOnce(queryParams.value).then((response) => {
  291. orderList.value = response.rows.map((l) => ({
  292. ...l,
  293. editStatus: proxy.deepClone(editStatus),
  294. }));
  295. prev.value = proxy.deepClone(response.rows);
  296. total.value = response.total;
  297. loading.value = false;
  298. });
  299. }
  300. /** 搜索按钮操作 */
  301. function handleQuery() {
  302. queryParams.value.pageNum = 1;
  303. getList();
  304. }
  305. /** 重置按钮操作 */
  306. function resetQuery() {
  307. proxy.resetForm("queryRef");
  308. handleQuery();
  309. }
  310. // 多选框选中数据
  311. function handleSelectionChange(selection) {
  312. ids.value = selection.map((item) => item.id);
  313. single.value = selection.length != 1;
  314. multiple.value = !selection.length;
  315. }
  316. /** 新增按钮操作 */
  317. function handleAdd() {
  318. formOpen.value = true;
  319. }
  320. function formCancel() {
  321. formOpen.value = false;
  322. reset();
  323. }
  324. function reset() {
  325. form.value = proxy.deepClone(emptyForm);
  326. }
  327. /** 修改按钮操作 */
  328. function handleUpdate(row) {}
  329. /** 删除按钮操作 */
  330. function handleDelete(row) {
  331. const _ids = row.id || ids.value;
  332. proxy.$modal
  333. .confirm("是否确认删除选中的数据项?")
  334. .then(function () {
  335. return delWorkOrder(_ids);
  336. })
  337. .then(() => {
  338. getList();
  339. proxy.$modal.msgSuccess("删除成功!");
  340. })
  341. .catch(() => {});
  342. }
  343. /** 导出按钮操作 */
  344. function handleExport() {
  345. exportOnce(queryParams.value);
  346. }
  347. function startDateChangeHandler(row, startDate) {
  348. if (startDate) {
  349. // console.log(startDate)
  350. row.endMonth = proxy
  351. .moment(startDate)
  352. .add(row.monthNum - 1, "M")
  353. .format("YYYY-MM-DD");
  354. } else row.endMonth = null;
  355. console.log(row);
  356. }
  357. function saveHandler() {
  358. if (form.value.id == null) {
  359. addWorkOrder(form.value).then((res) => {
  360. formCancel();
  361. getList();
  362. });
  363. }
  364. }
  365. function setServiceHandler() {
  366. if (ids.value.length === 0) {
  367. proxy.$modal.msgError("请先选择需要设置的工单!");
  368. return;
  369. }
  370. proxy.$refs["serviceRef"].open({
  371. dialogTitle: "设置执行人",
  372. dialogContent: "请输入执行人姓名",
  373. values: ids.value,
  374. });
  375. }
  376. function getStatusStyle(row) {
  377. const record = row.records.find((v) => v.fromId === "0");
  378. if (record == null) {
  379. return { color: getStatusColor(0), verticalAlign: "middle" };
  380. } else {
  381. return { color: getStatusColor(record.status), verticalAlign: "middle" };
  382. }
  383. }
  384. function getStatusColor(status) {
  385. const index = selectStatus.value.findIndex((v) => v.value === status);
  386. return index >= 0 ? selectStatus.value[index].color : "#fff";
  387. }
  388. function getStatusLabel(row) {
  389. const record = row.records.find((v) => v.fromId === "0");
  390. const index = selectStatus.value.findIndex(
  391. (v) => v.value === (record == null ? 0 : record.status)
  392. );
  393. return index >= 0 ? selectStatus.value[index].label : "";
  394. }
  395. function handleByRow(row) {
  396. const record = row.records.find((v) => v.fromId === "0");
  397. const editable =
  398. permissions.includes(all_permission) ||
  399. permissions.includes("business:customer:service:loop:edit") >= 0;
  400. const viewable =
  401. permissions.includes(all_permission) ||
  402. permissions.includes("business:customer:service:loop:view") >= 0;
  403. if (record == null && row.isStop == 1) {
  404. proxy.$modal.msg("工单已终止");
  405. return;
  406. }
  407. if (
  408. record != null &&
  409. (record.status === 3 || row.isStop == 1) &&
  410. (editable || viewable)
  411. ) {
  412. viewRef.value.open({
  413. workOrderId: row.id,
  414. companyId: row.companyId,
  415. companyName: row.companyName,
  416. });
  417. } else if (
  418. row.entrusts != null &&
  419. row.entrusts.length > 0 &&
  420. (editable || viewable)
  421. ) {
  422. if (row.entrusts.length >= 0) {
  423. viewRef.value.open({
  424. workOrderId: row.id,
  425. companyId: row.companyId,
  426. companyName: row.companyName,
  427. });
  428. } else if (editable) {
  429. formRef.value.open({
  430. workOrderId: row.id,
  431. companyId: row.companyId,
  432. companyName: row.companyName,
  433. });
  434. } else {
  435. proxy.$modal.msg("没有修改权限");
  436. }
  437. } else if (editable) {
  438. formRef.value.open({
  439. workOrderId: row.id,
  440. companyId: row.companyId,
  441. companyName: row.companyName,
  442. });
  443. } else {
  444. proxy.$modal.msg("没有修改权限");
  445. }
  446. }
  447. function getTransactor(row) {
  448. if (row.entrusts != null && row.entrusts.length > 0) {
  449. const names = Array.from(new Set(row.entrusts.map((v) => v.toAccountName)));
  450. return names.join(",");
  451. } else {
  452. return row.serviceName;
  453. }
  454. }
  455. function clearStatus() {
  456. queryParams.value.status = null;
  457. }
  458. function hasPermi(arr) {
  459. return auth.hasPermiOr(arr);
  460. }
  461. getList();
  462. </script>