addEditor.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. <template>
  2. <div class="w-full h-full flex flex-col">
  3. <div class="flex-1 overflow-y-auto">
  4. <van-form ref="vanFormRef" show-error :show-error-message="false" label-align="left" input-align="right"
  5. class="bg-white" @submit="onSubmit">
  6. <van-field v-model="vantFormVal.taskName" name="taskName" rows="2" label="任务名称" maxlength="100" required
  7. show-word-limit type="textarea" placeholder="请输入" />
  8. <van-field v-model="vantFormVal.priority" name="priority" label="优先级" placeholder="请选择" is-link readonly
  9. required @click="showSelectionBox('priority', fixedFieldPriority)">
  10. <template #input v-if="vantFormVal.priority || vantFormVal.priority == 0">
  11. {{ vantFormVal.priorityName }}
  12. </template>
  13. </van-field>
  14. <van-field v-model="vantFormVal.taskType" name="taskType" label="任务类型" placeholder="请选择" is-link readonly
  15. @click="showSelectionBox('taskType', fixedFieldTaskType)" class="resetStyles">
  16. <template #input v-if="vantFormVal.taskType || vantFormVal.taskType == 0">
  17. {{ vantFormVal.taskTypeName }}
  18. </template>
  19. </van-field>
  20. <!-- 客户选择 -->
  21. <template v-if="vantFormVal.taskType == 0">
  22. <van-field v-model="vantFormVal.customId" name="customId" label="客户" placeholder="请选择" is-link readonly
  23. @click="showSelectionBox('customId', allCustomersList)" class="resetStyles">
  24. <template #input v-if="vantFormVal.customId">
  25. {{ vantFormVal.customIdName }}
  26. </template>
  27. </van-field>
  28. </template>
  29. <!-- 商机选择 -->
  30. <template v-if="vantFormVal.taskType == 1">
  31. <van-field v-model="vantFormVal.businessOpportunityId" name="businessOpportunityId" label="商机"
  32. placeholder="请选择" is-link readonly class="resetStyles"
  33. @click="showSelectionBox('businessOpportunityId', allBusinessOpportunities)">
  34. <template #input v-if="vantFormVal.businessOpportunityId">
  35. {{ vantFormVal.businessOpportunityIdName }}
  36. </template>
  37. </van-field>
  38. </template>
  39. <!-- 销售订单选择 -->
  40. <template v-if="vantFormVal.taskType == 2">
  41. <van-field v-model="vantFormVal.orderId" name="orderId" label="销售订单" placeholder="请选择" is-link readonly
  42. class="resetStyles" @click="showSelectionBox('orderId', allSalesOrdersList)">
  43. <template #input v-if="vantFormVal.orderId">
  44. {{ vantFormVal.orderIdName }}
  45. </template>
  46. </van-field>
  47. </template>
  48. <!-- 线索选择 -->
  49. <template v-if="vantFormVal.taskType == 3">
  50. <van-field v-model="vantFormVal.clueId" name="clueId" label="线索" placeholder="请选择" is-link readonly
  51. class="resetStyles" @click="showSelectionBox('clueId', allCluesList)">
  52. <template #input v-if="vantFormVal.clueId">
  53. {{ vantFormVal.clueIdName }}
  54. </template>
  55. </van-field>
  56. </template>
  57. <van-field v-model="vantFormVal.contactsId" name="contactsId" label="联系人" placeholder="请选择" is-link readonly
  58. :disabled="contactDisabled"
  59. v-if="fixedFieldTaskType.find(v => v.value == (vantFormVal.taskType || '1'))?.show" class="resetStyles"
  60. @click="showSelectionBox('contactsId', allContactsList)">
  61. <template #input v-if="vantFormVal.contactsId">
  62. {{ vantFormVal.contactsIdName }}
  63. </template>
  64. </van-field>
  65. <van-field v-model="vantFormVal.executorId" name="executorId" label="执行人" placeholder="请选择" is-link readonly
  66. class="resetStyles" @click="showSelectionToBox('executorId')">
  67. <template #input v-if="vantFormVal.executorIdName && vantFormVal.executorIdName.length > 0">
  68. <TranslationComponent :openId="vantFormVal.executorIdName" />
  69. </template>
  70. </van-field>
  71. <van-field name="isRepeat" label="重复提醒" class="resetStyles">
  72. <template #input>
  73. <van-switch v-model="vantFormVal.isRepeat" size="small" />
  74. </template>
  75. </van-field>
  76. <!-- 重复提醒 -->
  77. <template v-if="vantFormVal.isRepeat">
  78. <van-field v-model="vantFormVal.repeatType" name="repeatType" label="重复类型" placeholder="请选择" is-link readonly
  79. class="resetStyles" @click="showSelectionBox('repeatType', fixedFieldRepetitiveType)">
  80. <template #input v-if="vantFormVal.repeatType">
  81. {{ vantFormVal.repeatTypeName }}
  82. </template>
  83. </van-field>
  84. <template v-if="[0, 1, 2, 3, '0', '1', '2', '3'].includes(vantFormVal.repeatType)">
  85. <van-field v-model="vantFormVal.repeatDesignSameday" type="digit" name="repeatDesignSameday" label="每"
  86. class="resetStyles" v-if="vantFormVal.repeatType == 3">
  87. <template #input>
  88. <van-stepper v-model="vantFormVal.repeatDesignSameday" :min="0" button-size="1.2rem" theme="round"
  89. integer class="mr-2" />
  90. </template>
  91. <template #extra> 天 </template>
  92. </van-field>
  93. <van-field name="endType" label="结束" class="resetStyles">
  94. <template #input>
  95. <van-radio-group v-model="vantFormVal.endType" direction="horizontal" class="flex flex-col"
  96. @change="radiogroupChange">
  97. <van-radio name="1"><span
  98. :class="vantFormVal.endType == 1 ? 'themeTextColor' : ''">永不</span></van-radio>
  99. <van-radio name="2" class="mt-3">
  100. <van-stepper v-model="vantFormVal.repeatEndCount" :disabled="vantFormVal.endType != 2" :min="0"
  101. button-size="1.2rem" theme="round" integer class="mr-2" />
  102. 次数以后
  103. </van-radio>
  104. <van-radio name="3" class="mt-3">
  105. <div class="flex items-center">
  106. <van-field label="日期" is-link readonly :disabled="vantFormVal.endType != 3" class="selectField"
  107. placeholder="请选择" @click="vantFormVal.endType == 3 && showDatePickerBox('repeatEndDate')">
  108. <template #input v-if="vantFormVal.repeatEndDate">
  109. {{ vantFormVal.repeatEndDate }}
  110. </template>
  111. </van-field>
  112. 以后
  113. </div>
  114. </van-radio>
  115. </van-radio-group>
  116. </template>
  117. </van-field>
  118. </template>
  119. <template v-if="[4, '4'].includes(vantFormVal.repeatType)">
  120. <div class="flex items-center justify-between px-8 pt-3">
  121. <div>自定义日期</div>
  122. <div><van-icon name="add-o" class="ml-2 themeTextColor" size="1.3rem" @click="addCustomeDateItem()" />
  123. </div>
  124. </div>
  125. <van-cell-group inset class="additionalCoAuthorship">
  126. <template v-for="(item, index) in customeDate">
  127. <van-cell :title="`第${index + 1}次重复在`">
  128. <template #default>
  129. <div class="flex items-center justify-end">
  130. <van-stepper v-model="item.value" :min="0" button-size="1.2rem" theme="round" integer
  131. class="mr-2" />
  132. 之后
  133. <van-icon name="delete-o" class="ml-2 text-[red]" size="1.3rem"
  134. @click="deleteCustomeDateItem(index)" />
  135. </div>
  136. </template>
  137. </van-cell>
  138. </template>
  139. </van-cell-group>
  140. </template>
  141. </template>
  142. <van-field label="开始时间" name="startDate" is-link readonly class="resetStyles" placeholder="请选择"
  143. @click="showDatePickerBox('startDate')">
  144. <template #input v-if="vantFormVal.startDate">
  145. {{ vantFormVal.startDate }}
  146. </template>
  147. </van-field>
  148. <van-field label="结束时间" name="endDate" is-link readonly class="resetStyles" placeholder="请选择"
  149. @click="showDatePickerBox('endDate')">
  150. <template #input v-if="vantFormVal.endDate">
  151. {{ vantFormVal.endDate }}
  152. </template>
  153. </van-field>
  154. <div></div>
  155. </van-form>
  156. <CustomerForm ref="formFormRef" :formJson="formJson" :formValue="formVal"></CustomerForm>
  157. </div>
  158. <div class="mar-20px ">
  159. <van-button type="primary" @click="onSubmit" class="w-full">
  160. {{ Object.keys(formVal).length > 0 ? '确定修改' : '确定添加' }}
  161. </van-button>
  162. </div>
  163. <!-- 选择器 -->
  164. <div>
  165. <!-- 下拉框选择 -->
  166. <van-popup v-model:show="showSelectionFlag" destroy-on-close position="bottom" :style="{ height: '80%' }">
  167. <PullDownSelector :options="showSelectionArray" :doYouNeedTranslation="false" @change="selectChange" />
  168. </van-popup>
  169. <van-popup v-model:show="showSelectionToFlag" destroy-on-close position="bottom" :style="{ height: '80%' }">
  170. <PullDownSelector :value="showSelectionToValue" @change="selectChange" :multiple-choice="true" />
  171. </van-popup>
  172. <!-- 选择日期 -->
  173. <van-popup v-model:show="showDatePicker" destroy-on-close position="bottom" :style="{ height: '50%' }">
  174. <van-date-picker v-model="showDatePickerVal" @confirm="showPickerConfirm" @cancel="showDatePicker = false" />
  175. </van-popup>
  176. </div>
  177. </div>
  178. </template>
  179. <script setup>
  180. import { ref, onActivated, computed } from 'vue';
  181. import { useLifecycle } from '@hooks/useCommon.js';
  182. import { fixedFieldTaskType, fixedFieldPriority, fixedFieldRepetitiveType } from '@utility/defaultData.js';
  183. import { GET_ALL_CUSTOMERSLIST, GET_ALL_BUSINESS_OPPORTUNITIES, GET_SALES_ORDER_LIST, GET_OBTAIN_ALL_CLUES, GET_CONTACTS_WITH_MORE_I_DS, TASK_ADD_EDIT } from "@hooks/useApi";
  184. import requests from "@common/requests";
  185. import useToast from "@hooks/useToast"
  186. import dayjs from 'dayjs';
  187. import PullDownSelector from '@components/common/pullDownSelector.vue'
  188. import CustomerForm from '@components/common/formForm/formView.vue'
  189. import TranslationComponent from '@components/common/translationComponent.vue';
  190. import useRouterStore from "@store/useRouterStore.js";
  191. const router = useRouterStore()
  192. const { toastText, toastSuccess, toastFail, toastLoading } = useToast()
  193. const props = defineProps({
  194. formJson: { required: true },
  195. formValue: { required: true },
  196. });
  197. const formFormRef = ref(null)
  198. const vantFormVal = ref({
  199. taskType: 0,
  200. taskTypeName: '客户',
  201. endType: '1',
  202. repeatEndCount: 0,
  203. repeatType: 0,
  204. repeatTypeName: '每天'
  205. })
  206. const formVal = ref({})
  207. const allBusinessOpportunities = ref([])
  208. const allCustomersList = ref([])
  209. const allCluesList = ref([])
  210. const allSalesOrdersList = ref([])
  211. const allContactsList = ref([])
  212. const showSelectionFlag = ref(false)
  213. const showSelectionFiled = ref([])
  214. const showSelectionArray = ref([])
  215. const showDatePicker = ref(false)
  216. const showDatePickerVal = ref(dayjs().format("YYYY-MM-DD").split("-"))
  217. const showDatePickerFiled = ref('')
  218. const customeDate = ref([])
  219. const showSelectionToFlag = ref(false)
  220. const showSelectionToValue = ref([])
  221. const taskTypeFiled = ['customId', 'businessOpportunityId', 'orderId', 'clueId']
  222. const contactDisabled = computed(() => {
  223. const taskType = vantFormVal.value?.taskType
  224. if (!taskType && taskType != 0) {
  225. return true
  226. }
  227. if (taskType == 0 && !vantFormVal.value.customId) {
  228. return true
  229. }
  230. if (taskType == 1 && !vantFormVal.value.businessOpportunityId) {
  231. return true
  232. }
  233. if (taskType == 2 && !vantFormVal.value.orderId) {
  234. return true
  235. }
  236. return false
  237. })
  238. function onSubmit() {
  239. formFormRef.value.getJsonData().then((res) => {
  240. const formValue = {
  241. ...vantFormVal.value,
  242. ...formVal.value,
  243. ...res.data,
  244. repeatDesignDay: customeDate.value.map(item => item.value).join(','),
  245. executorId: vantFormVal.value.executorId,
  246. isRepeat: vantFormVal.value.isRepeat ? 1 : 0
  247. }
  248. console.log('formValue', formValue)
  249. toastLoading('保存中')
  250. requests.post(TASK_ADD_EDIT, { ...formValue }).then(() => {
  251. toastSuccess('保存成功')
  252. setTimeout(() => {
  253. router.navigateBack({
  254. success: () => {
  255. router.eventEmit('moduleListRefreshData', {})
  256. }
  257. })
  258. }, 2000)
  259. }).finally(() => {
  260. })
  261. })
  262. }
  263. function showPickerConfirm({ selectedValues }) {
  264. vantFormVal.value[showDatePickerFiled.value] = selectedValues.join('-')
  265. showDatePicker.value = false
  266. }
  267. function showDatePickerBox(filed) {
  268. const dateVal = vantFormVal.value[filed] ? vantFormVal.value[filed] : dayjs().format("YYYY-MM-DD")
  269. showDatePickerFiled.value = filed
  270. showDatePickerVal.value = dateVal.split("-")
  271. showDatePicker.value = true
  272. }
  273. function selectChange(value, label) {
  274. if (taskTypeFiled.includes(showSelectionFiled.value)) {
  275. const item = fixedFieldTaskType.find(item => item.value == vantFormVal.value.taskType)
  276. console.log(item, value,)
  277. if (item && item.show) {
  278. getContactData(showSelectionFiled.value, value)
  279. }
  280. }
  281. if (showSelectionFiled.value == 'repeatType') {
  282. vantFormVal.value = {
  283. ...vantFormVal.value,
  284. endType: 0,
  285. repeatEndCount: 0,
  286. repeatEndDate: null
  287. }
  288. customeDate.value = []
  289. }
  290. vantFormVal.value[showSelectionFiled.value] = value
  291. vantFormVal.value[`${showSelectionFiled.value}Name`] = label
  292. showSelectionFlag.value = false
  293. }
  294. function showSelectionToBox(filed) {
  295. showSelectionFiled.value = filed
  296. showSelectionToValue.value = vantFormVal.value[filed] || []
  297. showSelectionToFlag.value = true
  298. }
  299. function showSelectionBox(filed, list = [], event) {
  300. if (taskTypeFiled.includes(filed)) {
  301. const fileds = taskTypeFiled.filter(item => item !== filed)
  302. fileds.forEach(item => {
  303. vantFormVal.value[item] = ''
  304. vantFormVal.value[`${item}Name`] = ''
  305. })
  306. vantFormVal.value.contactsId = ''
  307. vantFormVal.value[`contactsIdName`] = ''
  308. }
  309. showSelectionFiled.value = filed
  310. showSelectionArray.value = filed == 'executorId' ? [] : list
  311. showSelectionFlag.value = true
  312. }
  313. function addCustomeDateItem() {
  314. customeDate.value.push({ value: null })
  315. }
  316. function deleteCustomeDateItem(index) {
  317. customeDate.value.splice(index, 1)
  318. }
  319. function radiogroupChange(val) {
  320. switch (val) {
  321. case 1:
  322. vantFormVal.value.repeatEndDate = ''
  323. vantFormVal.value.repeatEndCount = null
  324. break;
  325. case 2:
  326. vantFormVal.value.repeatEndDate = ''
  327. break;
  328. case 3:
  329. vantFormVal.value.repeatEndCount = null
  330. break;
  331. default:
  332. break;
  333. }
  334. }
  335. function getContactData(filed, value) {
  336. const urlType = {
  337. 'customId': 'customerId',
  338. 'businessOpportunityId': 'businessId',
  339. 'orderId': 'salesId',
  340. }
  341. const url = `${GET_CONTACTS_WITH_MORE_I_DS}?${urlType[filed]}=${value}`
  342. requests.get(url).then(({ data = [] }) => {
  343. let list = data.map(item => {
  344. return {
  345. label: item.name,
  346. value: item.id,
  347. }
  348. })
  349. if (!list.length) {
  350. list = [{}]
  351. }
  352. allContactsList.value = list
  353. })
  354. }
  355. function getAllListData() {
  356. requests.post(GET_ALL_CUSTOMERSLIST, {}).then(res => {
  357. allCustomersList.value = res.data.map(item => {
  358. return {
  359. label: item.customName,
  360. value: item.id,
  361. }
  362. })
  363. })
  364. requests.post(GET_ALL_BUSINESS_OPPORTUNITIES, {}).then(res => {
  365. allBusinessOpportunities.value = res.data.map(item => {
  366. return {
  367. label: item.name,
  368. value: item.id,
  369. }
  370. })
  371. })
  372. requests.post(GET_SALES_ORDER_LIST, { pageIndex: -1, pageSize: -1 }).then(({ data }) => {
  373. allSalesOrdersList.value = (data.record || []).map(item => {
  374. return {
  375. label: item.orderName,
  376. value: item.id,
  377. }
  378. })
  379. })
  380. requests.post(GET_OBTAIN_ALL_CLUES, {}).then(res => {
  381. allCluesList.value = res.data.map(item => {
  382. return {
  383. label: item.clueName,
  384. value: item.id,
  385. }
  386. })
  387. })
  388. }
  389. function initializeData() {
  390. const row = props.formValue
  391. if (!row.id) {
  392. vantFormVal.value = {
  393. taskType: 0,
  394. taskTypeName: '客户',
  395. endType: '1',
  396. repeatEndCount: 0,
  397. repeatType: 0,
  398. repeatTypeName: '每天'
  399. }
  400. formVal.value = props.formValue
  401. customeDate.value = []
  402. return
  403. }
  404. const { id, taskName, priority, taskType, customId, customName, businessOpportunityId, businessOpportunityName, orderId, orderName, clueId, clueNme, contactsId, contactsName
  405. , taskExecutors, isRepeat, repeatType, repeatDesignSameday, endType, repeatEndCount, repeatEndDate, repeatDesignDay, executorId, startDate, endDate } = row
  406. vantFormVal.value = {
  407. id, taskName, priority, taskType, customId, businessOpportunityId, orderId, clueId, contactsId, executorId, repeatType, repeatDesignSameday, endType, repeatEndCount, repeatEndDate, startDate, endDate,
  408. isRepeat: isRepeat == 1 ? true : false,
  409. executorIdName: taskExecutors || [],
  410. contactsIdName: contactsName,
  411. clueIdNme: clueNme,
  412. orderIdName: orderName,
  413. customIdName: customName,
  414. businessOpportunityIdName: businessOpportunityName,
  415. priorityName: fixedFieldPriority.find(item => item.value == priority)?.label || '',
  416. taskTypeName: fixedFieldTaskType.find(item => item.value == taskType)?.label || '',
  417. repeatTypenName: fixedFieldRepetitiveType.find(item => item.value == repeatType)?.label || ''
  418. }
  419. const list = repeatDesignDay && repeatDesignDay.split(',') || []
  420. customeDate.value = (list || []).map(item => {
  421. return {
  422. value: item
  423. }
  424. })
  425. formVal.value = props.formValue
  426. if ((taskType || taskType == 0) && taskType != 3) {
  427. const filed = taskType == 0 ? 'customId' : taskType == 1 ? 'businessOpportunityId' : taskType == 2 ? 'orderId' : 'clueId'
  428. const value = taskType == 0 ? customId : taskType == 1 ? businessOpportunityId : taskType == 2 ? orderId : clueId
  429. if (value) {
  430. getContactData(filed, value)
  431. }
  432. }
  433. }
  434. useLifecycle({
  435. load: () => {
  436. initializeData()
  437. getAllListData()
  438. },
  439. init: () => {
  440. initializeData()
  441. getAllListData()
  442. }
  443. });
  444. onActivated(() => {
  445. })
  446. </script>
  447. <style lang='scss' scoped>
  448. .selectField {
  449. padding: 0;
  450. width: 12rem;
  451. margin-right: 4px;
  452. }
  453. .selectField :deep(.van-cell__title) {
  454. width: 4rem;
  455. }
  456. .additionalCoAuthorship {
  457. border-bottom: 1px solid #EBEDF0
  458. }
  459. </style>